gtkcalendar.h \
gtkcellarea.h \
gtkcellareabox.h \
- gtkcellareaboxiter.h \
- gtkcellareaiter.h \
+ gtkcellareaboxcontext.h \
+ gtkcellareacontext.h \
gtkcelleditable.h \
gtkcelllayout.h \
gtkcellrenderer.h \
gtkcalendar.c \
gtkcellarea.c \
gtkcellareabox.c \
- gtkcellareaboxiter.c \
- gtkcellareaiter.c \
+ gtkcellareaboxcontext.c \
+ gtkcellareacontext.c \
gtkcelleditable.c \
gtkcelllayout.c \
gtkcellrenderer.c \
#include <gtk/gtkcalendar.h>
#include <gtk/gtkcellarea.h>
#include <gtk/gtkcellareabox.h>
-#include <gtk/gtkcellareaiter.h>
+#include <gtk/gtkcellareacontext.h>
#include <gtk/gtkcelleditable.h>
#include <gtk/gtkcelllayout.h>
#include <gtk/gtkcellrenderer.h>
#include "gtkintl.h"
#include "gtkcelllayout.h"
#include "gtkcellarea.h"
-#include "gtkcellareaiter.h"
+#include "gtkcellareacontext.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
/* GtkCellAreaClass */
static gint gtk_cell_area_real_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
static void gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width);
static gboolean gtk_cell_area_real_can_focus (GtkCellArea *area);
static gboolean gtk_cell_area_real_activate (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
class->render = NULL;
/* geometry */
- class->create_iter = NULL;
+ class->create_context = NULL;
class->get_request_mode = NULL;
class->get_preferred_width = NULL;
class->get_preferred_height = NULL;
*************************************************************/
static gint
gtk_cell_area_real_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
static void
gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
/* If the area doesnt do height-for-width, fallback on base preferred height */
- GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, iter, widget, minimum_height, natural_height);
+ GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, minimum_height, natural_height);
}
static void
gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width)
{
/* If the area doesnt do width-for-height, fallback on base preferred width */
- GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, iter, widget, minimum_width, natural_width);
+ GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, minimum_width, natural_width);
}
static void
static gboolean
gtk_cell_area_real_activate (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
/* Get the allocation of the focused cell.
*/
- gtk_cell_area_get_cell_allocation (area, iter, widget, priv->focus_cell,
+ gtk_cell_area_get_cell_allocation (area, context, widget, priv->focus_cell,
cell_area, &background_area);
/* Activate or Edit the currently focused cell
/**
* gtk_cell_area_get_cell_allocation:
* @area: a #GtkCellArea
- * @iter: the #GtkCellAreaIter used to hold sizes for @area.
+ * @context: the #GtkCellAreaContext used to hold sizes for @area.
* @widget: the #GtkWidget that @area is rendering on
* @renderer: the #GtkCellRenderer to get the allocation for
* @cell_area: the whole allocated area for @area in @widget
*/
void
gtk_cell_area_get_cell_allocation (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
GtkCellAreaClass *class;
g_return_if_fail (GTK_IS_CELL_AREA (area));
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
g_return_if_fail (cell_area != NULL);
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->get_cell_allocation)
- class->get_cell_allocation (area, iter, widget, renderer, cell_area, allocation);
+ class->get_cell_allocation (area, context, widget, renderer, cell_area, allocation);
else
g_warning ("GtkCellAreaClass::get_cell_allocation not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
gint
gtk_cell_area_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellAreaClass *class;
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
- g_return_val_if_fail (GTK_IS_CELL_AREA_ITER (iter), 0);
+ g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), 0);
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
g_return_val_if_fail (event != NULL, 0);
g_return_val_if_fail (cell_area != NULL, 0);
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->event)
- return class->event (area, iter, widget, event, cell_area, flags);
+ return class->event (area, context, widget, event, cell_area, flags);
g_warning ("GtkCellAreaClass::event not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
void
gtk_cell_area_render (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
GtkCellAreaClass *class;
g_return_if_fail (GTK_IS_CELL_AREA (area));
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (cr != NULL);
g_return_if_fail (background_area != NULL);
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->render)
- class->render (area, iter, widget, cr, background_area, cell_area, flags, paint_focus);
+ class->render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
else
g_warning ("GtkCellAreaClass::render not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
/*************************************************************
* API: Geometry *
*************************************************************/
-GtkCellAreaIter *
-gtk_cell_area_create_iter (GtkCellArea *area)
+GtkCellAreaContext *
+gtk_cell_area_create_context (GtkCellArea *area)
{
GtkCellAreaClass *class;
class = GTK_CELL_AREA_GET_CLASS (area);
- if (class->create_iter)
- return class->create_iter (area);
+ if (class->create_context)
+ return class->create_context (area);
- g_warning ("GtkCellAreaClass::create_iter not implemented for `%s'",
+ g_warning ("GtkCellAreaClass::create_context not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
return NULL;
void
gtk_cell_area_get_preferred_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->get_preferred_width)
- class->get_preferred_width (area, iter, widget, minimum_size, natural_size);
+ class->get_preferred_width (area, context, widget, minimum_size, natural_size);
else
g_warning ("GtkCellAreaClass::get_preferred_width not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
void
gtk_cell_area_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
g_return_if_fail (GTK_IS_WIDGET (widget));
class = GTK_CELL_AREA_GET_CLASS (area);
- class->get_preferred_height_for_width (area, iter, widget, width, minimum_height, natural_height);
+ class->get_preferred_height_for_width (area, context, widget, width, minimum_height, natural_height);
}
void
gtk_cell_area_get_preferred_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->get_preferred_height)
- class->get_preferred_height (area, iter, widget, minimum_size, natural_size);
+ class->get_preferred_height (area, context, widget, minimum_size, natural_size);
else
g_warning ("GtkCellAreaClass::get_preferred_height not implemented for `%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
void
gtk_cell_area_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
g_return_if_fail (GTK_IS_WIDGET (widget));
class = GTK_CELL_AREA_GET_CLASS (area);
- class->get_preferred_width_for_height (area, iter, widget, height, minimum_width, natural_width);
+ class->get_preferred_width_for_height (area, context, widget, height, minimum_width, natural_width);
}
/*************************************************************
/**
* gtk_cell_area_activate:
* @area: a #GtkCellArea
- * @iter: the #GtkCellAreaIter in context with the current row data
+ * @context: the #GtkCellAreaContext in context with the current row data
* @widget: the #GtkWidget that @area is rendering on
* @cell_area: the size and location of @area relative to @widget's allocation
* @flags: the #GtkCellRendererState flags for @area for this row of data.
*/
gboolean
gtk_cell_area_activate (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
- return GTK_CELL_AREA_GET_CLASS (area)->activate (area, iter, widget, cell_area, flags);
+ return GTK_CELL_AREA_GET_CLASS (area)->activate (area, context, widget, cell_area, flags);
}
typedef struct _GtkCellArea GtkCellArea;
typedef struct _GtkCellAreaClass GtkCellAreaClass;
typedef struct _GtkCellAreaPrivate GtkCellAreaPrivate;
-typedef struct _GtkCellAreaIter GtkCellAreaIter;
+typedef struct _GtkCellAreaContext GtkCellAreaContext;
/**
* GtkCellCallback:
GtkCellCallback callback,
gpointer callback_data);
void (* get_cell_allocation) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
GdkRectangle *allocation);
gint (* event) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
void (* render) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
gboolean paint_focus);
/* Geometry */
- GtkCellAreaIter *(* create_iter) (GtkCellArea *area);
+ GtkCellAreaContext *(* create_context) (GtkCellArea *area);
GtkSizeRequestMode (* get_request_mode) (GtkCellArea *area);
void (* get_preferred_width) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void (* get_preferred_height_for_width) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
void (* get_preferred_height) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void (* get_preferred_width_for_height) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gboolean (* focus) (GtkCellArea *area,
GtkDirectionType direction);
gboolean (* activate) (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
GtkCellCallback callback,
gpointer callback_data);
void gtk_cell_area_get_cell_allocation (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
GdkRectangle *allocation);
gint gtk_cell_area_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
void gtk_cell_area_render (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
G_CONST_RETURN gchar *gtk_cell_area_get_style_detail (GtkCellArea *area);
/* Geometry */
-GtkCellAreaIter *gtk_cell_area_create_iter (GtkCellArea *area);
+GtkCellAreaContext *gtk_cell_area_create_context (GtkCellArea *area);
GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area);
void gtk_cell_area_get_preferred_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void gtk_cell_area_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
void gtk_cell_area_get_preferred_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void gtk_cell_area_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gboolean gtk_cell_area_focus (GtkCellArea *area,
GtkDirectionType direction);
gboolean gtk_cell_area_activate (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
#include "gtkorientable.h"
#include "gtkcelllayout.h"
#include "gtkcellareabox.h"
-#include "gtkcellareaboxiter.h"
+#include "gtkcellareaboxcontext.h"
#include "gtkprivate.h"
GtkCellCallback callback,
gpointer callback_data);
static void gtk_cell_area_box_get_cell_allocation (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
GdkRectangle *allocation);
static gint gtk_cell_area_box_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
static void gtk_cell_area_box_render (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
guint prop_id,
GValue *value,
GParamSpec *pspec);
-static GtkCellAreaIter *gtk_cell_area_box_create_iter (GtkCellArea *area);
+static GtkCellAreaContext *gtk_cell_area_box_create_context (GtkCellArea *area);
static GtkSizeRequestMode gtk_cell_area_box_get_request_mode (GtkCellArea *area);
static void gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_width,
gint *natural_width);
static void gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_height,
gint *natural_height);
static void gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint size;
} AllocatedCell;
-static CellInfo *cell_info_new (GtkCellRenderer *renderer,
- GtkPackType pack,
- gboolean expand,
- gboolean align);
-static void cell_info_free (CellInfo *info);
-static gint cell_info_find (CellInfo *info,
- GtkCellRenderer *renderer);
-
-static AllocatedCell *allocated_cell_new (GtkCellRenderer *renderer,
- gint position,
- gint size);
-static void allocated_cell_free (AllocatedCell *cell);
-static GList *list_consecutive_cells (GtkCellAreaBox *box);
-static gint count_expand_groups (GtkCellAreaBox *box);
-static void iter_weak_notify (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *dead_iter);
-static void flush_iters (GtkCellAreaBox *box);
-static void init_iter_groups (GtkCellAreaBox *box);
-static void init_iter_group (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter);
-static GSList *get_allocated_cells (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter,
- GtkWidget *widget);
+static CellInfo *cell_info_new (GtkCellRenderer *renderer,
+ GtkPackType pack,
+ gboolean expand,
+ gboolean align);
+static void cell_info_free (CellInfo *info);
+static gint cell_info_find (CellInfo *info,
+ GtkCellRenderer *renderer);
+
+static AllocatedCell *allocated_cell_new (GtkCellRenderer *renderer,
+ gint position,
+ gint size);
+static void allocated_cell_free (AllocatedCell *cell);
+static GList *list_consecutive_cells (GtkCellAreaBox *box);
+static gint count_expand_groups (GtkCellAreaBox *box);
+static void context_weak_notify (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *dead_context);
+static void flush_contexts (GtkCellAreaBox *box);
+static void init_context_groups (GtkCellAreaBox *box);
+static void init_context_group (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *context);
+static GSList *get_allocated_cells (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *context,
+ GtkWidget *widget);
struct _GtkCellAreaBoxPrivate
GList *cells;
GArray *groups;
- GSList *iters;
+ GSList *contexts;
gint spacing;
};
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->groups = g_array_new (FALSE, TRUE, sizeof (CellGroup));
priv->cells = NULL;
- priv->iters = NULL;
+ priv->contexts = NULL;
priv->spacing = 0;
}
area_class->set_cell_property = gtk_cell_area_box_set_cell_property;
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
- area_class->create_iter = gtk_cell_area_box_create_iter;
+ area_class->create_context = gtk_cell_area_box_create_context;
area_class->get_request_mode = gtk_cell_area_box_get_request_mode;
area_class->get_preferred_width = gtk_cell_area_box_get_preferred_width;
area_class->get_preferred_height = gtk_cell_area_box_get_preferred_height;
group_ptr->cells = g_list_reverse (group_ptr->cells);
}
- /* Iters need to be updated with the new grouping information */
- init_iter_groups (box);
+ /* Contexts need to be updated with the new grouping information */
+ init_context_groups (box);
}
static gint
}
static void
-iter_weak_notify (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *dead_iter)
+context_weak_notify (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *dead_context)
{
GtkCellAreaBoxPrivate *priv = box->priv;
- priv->iters = g_slist_remove (priv->iters, dead_iter);
+ priv->contexts = g_slist_remove (priv->contexts, dead_context);
}
static void
-init_iter_group (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter)
+init_context_group (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *context)
{
GtkCellAreaBoxPrivate *priv = box->priv;
gint *expand_groups, i;
}
/* This call implies flushing the request info */
- gtk_cell_area_box_init_groups (iter, priv->groups->len, expand_groups);
+ gtk_cell_area_box_init_groups (context, priv->groups->len, expand_groups);
g_free (expand_groups);
}
static void
-init_iter_groups (GtkCellAreaBox *box)
+init_context_groups (GtkCellAreaBox *box)
{
GtkCellAreaBoxPrivate *priv = box->priv;
GSList *l;
- /* When the box's groups are reconstructed, iters need to
+ /* When the box's groups are reconstructed, contexts need to
* be reinitialized.
*/
- for (l = priv->iters; l; l = l->next)
+ for (l = priv->contexts; l; l = l->next)
{
- GtkCellAreaBoxIter *iter = l->data;
+ GtkCellAreaBoxContext *context = l->data;
- init_iter_group (box, iter);
+ init_context_group (box, context);
}
}
static void
-flush_iters (GtkCellAreaBox *box)
+flush_contexts (GtkCellAreaBox *box)
{
GtkCellAreaBoxPrivate *priv = box->priv;
GSList *l;
- /* When the box layout changes, iters need to
+ /* When the box layout changes, contexts need to
* be flushed and sizes for the box get requested again
*/
- for (l = priv->iters; l; l = l->next)
+ for (l = priv->contexts; l; l = l->next)
{
- GtkCellAreaIter *iter = l->data;
+ GtkCellAreaContext *context = l->data;
- gtk_cell_area_iter_flush (iter);
+ gtk_cell_area_context_flush (context);
}
}
* list of allocated cells to operate on.
*/
static GSList *
-get_allocated_cells (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter,
- GtkWidget *widget)
+get_allocated_cells (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *context,
+ GtkWidget *widget)
{
const GtkCellAreaBoxAllocation *group_allocs;
GtkCellArea *area = GTK_CELL_AREA (box);
GSList *allocated_cells = NULL;
gint i, j, n_allocs;
- group_allocs = gtk_cell_area_box_iter_get_orientation_allocs (iter, &n_allocs);
+ group_allocs = gtk_cell_area_box_context_get_orientation_allocs (context, &n_allocs);
if (!group_allocs)
{
- g_warning ("Trying to operate on an unallocated GtkCellAreaIter, "
- "GtkCellAreaBox requires that the iter be allocated at least "
+ g_warning ("Trying to operate on an unallocated GtkCellAreaContext, "
+ "GtkCellAreaBox requires that the context be allocated at least "
"in the orientation of the box");
return NULL;
}
GtkCellAreaBoxPrivate *priv = box->priv;
GSList *l;
- /* Unref/free the iter list */
- for (l = priv->iters; l; l = l->next)
- g_object_weak_unref (G_OBJECT (l->data), (GWeakNotify)iter_weak_notify, box);
+ /* Unref/free the context list */
+ for (l = priv->contexts; l; l = l->next)
+ g_object_weak_unref (G_OBJECT (l->data), (GWeakNotify)context_weak_notify, box);
- g_slist_free (priv->iters);
- priv->iters = NULL;
+ g_slist_free (priv->contexts);
+ priv->contexts = NULL;
/* Free the cell grouping info */
cell_groups_clear (box);
box->priv->orientation = g_value_get_enum (value);
/* Notify that size needs to be requested again */
- flush_iters (box);
+ flush_contexts (box);
break;
case PROP_SPACING:
gtk_cell_area_box_set_spacing (box, g_value_get_int (value));
static void
gtk_cell_area_box_get_cell_allocation (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxPrivate *priv = box->priv;
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
GSList *allocated_cells, *l;
*allocation = *cell_area;
/* Get a list of cells with allocation sizes decided regardless
* of alignments and pack order etc. */
- allocated_cells = get_allocated_cells (box, box_iter, widget);
+ allocated_cells = get_allocated_cells (box, box_context, widget);
for (l = allocated_cells; l; l = l->next)
{
static gint
gtk_cell_area_box_event (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
GdkEvent *event,
const GdkRectangle *cell_area,
/* First let the parent class handle activation of cells via keystrokes */
retval =
- GTK_CELL_AREA_CLASS (gtk_cell_area_box_parent_class)->event (area, iter, widget,
+ GTK_CELL_AREA_CLASS (gtk_cell_area_box_parent_class)->event (area, context, widget,
event, cell_area, flags);
if (retval)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxPrivate *priv = box->priv;
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
GSList *allocated_cells, *l;
GdkRectangle cell_background, inner_area;
gint event_x, event_y;
/* Get a list of cells with allocation sizes decided regardless
* of alignments and pack order etc. */
- allocated_cells = get_allocated_cells (box, box_iter, widget);
+ allocated_cells = get_allocated_cells (box, box_context, widget);
for (l = allocated_cells; l; l = l->next)
{
static void
gtk_cell_area_box_render (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxPrivate *priv = box->priv;
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
GSList *allocated_cells, *l;
GdkRectangle cell_background, inner_area;
GtkCellRenderer *focus_cell = NULL;
/* Get a list of cells with allocation sizes decided regardless
* of alignments and pack order etc. */
- allocated_cells = get_allocated_cells (box, box_iter, widget);
+ allocated_cells = get_allocated_cells (box, box_context, widget);
for (l = allocated_cells; l; l = l->next)
{
}
-static GtkCellAreaIter *
-gtk_cell_area_box_create_iter (GtkCellArea *area)
+static GtkCellAreaContext *
+gtk_cell_area_box_create_context (GtkCellArea *area)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxPrivate *priv = box->priv;
- GtkCellAreaIter *iter =
- (GtkCellAreaIter *)g_object_new (GTK_TYPE_CELL_AREA_BOX_ITER,
+ GtkCellAreaContext *context =
+ (GtkCellAreaContext *)g_object_new (GTK_TYPE_CELL_AREA_BOX_CONTEXT,
"area", area, NULL);
- priv->iters = g_slist_prepend (priv->iters, iter);
+ priv->contexts = g_slist_prepend (priv->contexts, context);
- g_object_weak_ref (G_OBJECT (iter), (GWeakNotify)iter_weak_notify, box);
+ g_object_weak_ref (G_OBJECT (context), (GWeakNotify)context_weak_notify, box);
/* Tell the new group about our cell layout */
- init_iter_group (box, GTK_CELL_AREA_BOX_ITER (iter));
+ init_context_group (box, GTK_CELL_AREA_BOX_CONTEXT (context));
- return iter;
+ return context;
}
static GtkSizeRequestMode
}
static void
-compute_size (GtkCellAreaBox *box,
- GtkOrientation orientation,
- GtkCellAreaBoxIter *iter,
- GtkWidget *widget,
- gint for_size,
- gint *minimum_size,
- gint *natural_size)
+compute_size (GtkCellAreaBox *box,
+ GtkOrientation orientation,
+ GtkCellAreaBoxContext *context,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
GtkCellArea *area = GTK_CELL_AREA (box);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (for_size < 0)
- gtk_cell_area_box_iter_push_group_width (iter, group->id, group_min_size, group_nat_size);
+ gtk_cell_area_box_context_push_group_width (context, group->id, group_min_size, group_nat_size);
else
- gtk_cell_area_box_iter_push_group_width_for_height (iter, group->id, for_size,
- group_min_size, group_nat_size);
+ gtk_cell_area_box_context_push_group_width_for_height (context, group->id, for_size,
+ group_min_size, group_nat_size);
}
else
{
if (for_size < 0)
- gtk_cell_area_box_iter_push_group_height (iter, group->id, group_min_size, group_nat_size);
+ gtk_cell_area_box_context_push_group_height (context, group->id, group_min_size, group_nat_size);
else
- gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
- group_min_size, group_nat_size);
+ gtk_cell_area_box_context_push_group_height_for_width (context, group->id, for_size,
+ group_min_size, group_nat_size);
}
}
}
static void
-compute_size_for_opposing_orientation (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter,
- GtkWidget *widget,
- gint for_size,
- gint *minimum_size,
- gint *natural_size)
+compute_size_for_opposing_orientation (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *context,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
CellGroup *group;
n_expand_groups = count_expand_groups (box);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
- orientation_sizes = gtk_cell_area_box_iter_get_widths (iter, &n_groups);
+ orientation_sizes = gtk_cell_area_box_context_get_widths (context, &n_groups);
else
- orientation_sizes = gtk_cell_area_box_iter_get_heights (iter, &n_groups);
+ orientation_sizes = gtk_cell_area_box_context_get_heights (context, &n_groups);
/* First start by naturally allocating space among groups of cells */
avail_size -= (n_groups - 1) * priv->spacing;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- gtk_cell_area_box_iter_push_group_height_for_width (iter, group_idx, for_size,
- group_min, group_nat);
+ gtk_cell_area_box_context_push_group_height_for_width (context, group_idx, for_size,
+ group_min, group_nat);
}
else
{
- gtk_cell_area_box_iter_push_group_width_for_height (iter, group_idx, for_size,
- group_min, group_nat);
+ gtk_cell_area_box_context_push_group_width_for_height (context, group_idx, for_size,
+ group_min, group_nat);
}
}
static void
gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_width,
gint *natural_width)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
- GtkCellAreaBoxIter *box_iter;
+ GtkCellAreaBoxContext *box_context;
gint min_width, nat_width;
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context));
- box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
/* Compute the size of all renderers for current row data,
- * bumping cell alignments in the iter along the way */
+ * bumping cell alignments in the context along the way */
compute_size (box, GTK_ORIENTATION_HORIZONTAL,
- box_iter, widget, -1, &min_width, &nat_width);
+ box_context, widget, -1, &min_width, &nat_width);
if (minimum_width)
*minimum_width = min_width;
static void
gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint *minimum_height,
gint *natural_height)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
- GtkCellAreaBoxIter *box_iter;
+ GtkCellAreaBoxContext *box_context;
gint min_height, nat_height;
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context));
- box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
/* Compute the size of all renderers for current row data,
- * bumping cell alignments in the iter along the way */
+ * bumping cell alignments in the context along the way */
compute_size (box, GTK_ORIENTATION_VERTICAL,
- box_iter, widget, -1, &min_height, &nat_height);
+ box_context, widget, -1, &min_height, &nat_height);
if (minimum_height)
*minimum_height = min_height;
static void
gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
- GtkCellAreaBoxIter *box_iter;
+ GtkCellAreaBoxContext *box_context;
GtkCellAreaBoxPrivate *priv;
gint min_height, nat_height;
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context));
- box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- priv = box->priv;
+ box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ priv = box->priv;
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
{
/* Add up vertical requests of height for width and push the overall
* cached sizes for alignments */
- compute_size (box, priv->orientation, box_iter, widget, width, &min_height, &nat_height);
+ compute_size (box, priv->orientation, box_context, widget, width, &min_height, &nat_height);
}
else
{
/* Juice: virtually allocate cells into the for_width using the
* alignments and then return the overall height for that width, and cache it */
- compute_size_for_opposing_orientation (box, box_iter, widget, width, &min_height, &nat_height);
+ compute_size_for_opposing_orientation (box, box_context, widget, width, &min_height, &nat_height);
}
if (minimum_height)
static void
gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea *area,
- GtkCellAreaIter *iter,
+ GtkCellAreaContext *context,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
- GtkCellAreaBoxIter *box_iter;
+ GtkCellAreaBoxContext *box_context;
GtkCellAreaBoxPrivate *priv;
gint min_width, nat_width;
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context));
- box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- priv = box->priv;
+ box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ priv = box->priv;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
/* Add up horizontal requests of width for height and push the overall
* cached sizes for alignments */
- compute_size (box, priv->orientation, box_iter, widget, height, &min_width, &nat_width);
+ compute_size (box, priv->orientation, box_context, widget, height, &min_width, &nat_width);
}
else
{
/* Juice: horizontally allocate cells into the for_height using the
* alignments and then return the overall width for that height, and cache it */
- compute_size_for_opposing_orientation (box, box_iter, widget, height, &min_width, &nat_width);
+ compute_size_for_opposing_orientation (box, box_context, widget, height, &min_width, &nat_width);
}
if (minimum_width)
g_object_notify (G_OBJECT (box), "spacing");
/* Notify that size needs to be requested again */
- flush_iters (box);
+ flush_contexts (box);
}
}
--- /dev/null
+/* gtkcellareaboxcontext.c
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb@openismus.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "gtkintl.h"
+#include "gtkcellareabox.h"
+#include "gtkcellareaboxcontext.h"
+#include "gtkorientable.h"
+
+/* GObjectClass */
+static void gtk_cell_area_box_context_finalize (GObject *object);
+
+/* GtkCellAreaContextClass */
+static void gtk_cell_area_box_context_flush_preferred_width (GtkCellAreaContext *context);
+static void gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width);
+static void gtk_cell_area_box_context_flush_preferred_height (GtkCellAreaContext *context);
+static void gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height);
+static void gtk_cell_area_box_context_flush_allocation (GtkCellAreaContext *context);
+static void gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context);
+static void gtk_cell_area_box_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width);
+static void gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context);
+static void gtk_cell_area_box_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height);
+static void gtk_cell_area_box_context_allocate_width (GtkCellAreaContext *context,
+ gint width);
+static void gtk_cell_area_box_context_allocate_height (GtkCellAreaContext *context,
+ gint height);
+
+static void free_cache_array (GArray *array);
+
+/* CachedSize management */
+typedef struct {
+ gint min_size;
+ gint nat_size;
+} CachedSize;
+
+typedef struct {
+ gint min_size;
+ gint nat_size;
+ gboolean expand;
+} BaseSize;
+
+struct _GtkCellAreaBoxContextPrivate
+{
+ /* Table of per renderer CachedSizes */
+ GArray *base_widths;
+ GArray *base_heights;
+
+ /* Table of per height/width hash tables of per renderer CachedSizes */
+ GHashTable *widths;
+ GHashTable *heights;
+
+ /* Allocation info for this context if any */
+ gint alloc_width;
+ gint alloc_height;
+ gint n_orientation_allocs;
+ GtkCellAreaBoxAllocation *orientation_allocs;
+};
+
+G_DEFINE_TYPE (GtkCellAreaBoxContext, gtk_cell_area_box_context, GTK_TYPE_CELL_AREA_CONTEXT);
+
+static void
+free_cache_array (GArray *array)
+{
+ g_array_free (array, TRUE);
+}
+
+static void
+gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+
+ box_context->priv = G_TYPE_INSTANCE_GET_PRIVATE (box_context,
+ GTK_TYPE_CELL_AREA_BOX_CONTEXT,
+ GtkCellAreaBoxContextPrivate);
+ priv = box_context->priv;
+
+ priv->base_widths = g_array_new (FALSE, TRUE, sizeof (BaseSize));
+ priv->base_heights = g_array_new (FALSE, TRUE, sizeof (BaseSize));
+
+ priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)free_cache_array);
+ priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)free_cache_array);
+
+ priv->alloc_width = 0;
+ priv->alloc_height = 0;
+ priv->orientation_allocs = NULL;
+ priv->n_orientation_allocs = 0;
+}
+
+static void
+gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkCellAreaContextClass *context_class = GTK_CELL_AREA_CONTEXT_CLASS (class);
+
+ /* GObjectClass */
+ object_class->finalize = gtk_cell_area_box_context_finalize;
+
+ context_class->flush_preferred_width = gtk_cell_area_box_context_flush_preferred_width;
+ context_class->flush_preferred_height_for_width = gtk_cell_area_box_context_flush_preferred_height_for_width;
+ context_class->flush_preferred_height = gtk_cell_area_box_context_flush_preferred_height;
+ context_class->flush_preferred_width_for_height = gtk_cell_area_box_context_flush_preferred_width_for_height;
+ context_class->flush_allocation = gtk_cell_area_box_context_flush_allocation;
+
+ context_class->sum_preferred_width = gtk_cell_area_box_context_sum_preferred_width;
+ context_class->sum_preferred_height_for_width = gtk_cell_area_box_context_sum_preferred_height_for_width;
+ context_class->sum_preferred_height = gtk_cell_area_box_context_sum_preferred_height;
+ context_class->sum_preferred_width_for_height = gtk_cell_area_box_context_sum_preferred_width_for_height;
+
+ context_class->allocate_width = gtk_cell_area_box_context_allocate_width;
+ context_class->allocate_height = gtk_cell_area_box_context_allocate_height;
+
+ g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxContextPrivate));
+}
+
+/*************************************************************
+ * GObjectClass *
+ *************************************************************/
+static void
+gtk_cell_area_box_context_finalize (GObject *object)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (object);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+
+ g_array_free (priv->base_widths, TRUE);
+ g_array_free (priv->base_heights, TRUE);
+ g_hash_table_destroy (priv->widths);
+ g_hash_table_destroy (priv->heights);
+
+ g_free (priv->orientation_allocs);
+
+ G_OBJECT_CLASS (gtk_cell_area_box_context_parent_class)->finalize (object);
+}
+
+/*************************************************************
+ * GtkCellAreaContextClass *
+ *************************************************************/
+static void
+gtk_cell_area_box_context_flush_preferred_width (GtkCellAreaContext *context)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ gint i;
+
+ for (i = 0; i < priv->base_widths->len; i++)
+ {
+ BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
+
+ size->min_size = 0;
+ size->nat_size = 0;
+ }
+
+ GTK_CELL_AREA_CONTEXT_CLASS
+ (gtk_cell_area_box_context_parent_class)->flush_preferred_width (context);
+}
+
+static void
+gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (width < 0)
+ g_hash_table_remove_all (priv->heights);
+ else
+ g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
+
+ GTK_CELL_AREA_CONTEXT_CLASS
+ (gtk_cell_area_box_context_parent_class)->flush_preferred_height_for_width (context, width);
+}
+
+static void
+gtk_cell_area_box_context_flush_preferred_height (GtkCellAreaContext *context)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ gint i;
+
+ for (i = 0; i < priv->base_heights->len; i++)
+ {
+ BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
+
+ size->min_size = 0;
+ size->nat_size = 0;
+ }
+
+ GTK_CELL_AREA_CONTEXT_CLASS
+ (gtk_cell_area_box_context_parent_class)->flush_preferred_height (context);
+}
+
+static void
+gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (height < 0)
+ g_hash_table_remove_all (priv->widths);
+ else
+ g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
+
+ GTK_CELL_AREA_CONTEXT_CLASS
+ (gtk_cell_area_box_context_parent_class)->flush_preferred_width_for_height (context, height);
+}
+
+static void
+gtk_cell_area_box_context_flush_allocation (GtkCellAreaContext *context)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+
+ g_free (priv->orientation_allocs);
+ priv->orientation_allocs = NULL;
+ priv->n_orientation_allocs = 0;
+}
+
+static void
+gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+ gint spacing, i;
+ gint min_size = 0, nat_size = 0;
+
+ area = gtk_cell_area_context_get_area (context);
+ spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ for (i = 0; i < priv->base_widths->len; i++)
+ {
+ BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ /* Dont add spacing for 0 size groups, they can be 0 size because
+ * they contain only invisible cells for this round of requests
+ */
+ if (min_size > 0 && size->nat_size > 0)
+ {
+ min_size += spacing;
+ nat_size += spacing;
+ }
+
+ min_size += size->min_size;
+ nat_size += size->nat_size;
+ }
+ else
+ {
+ min_size = MAX (min_size, size->min_size);
+ nat_size = MAX (nat_size, size->nat_size);
+ }
+ }
+
+ gtk_cell_area_context_push_preferred_width (context, min_size, nat_size);
+}
+
+static void
+gtk_cell_area_box_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GArray *group_array;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+ gint spacing, i;
+ gint min_size = 0, nat_size = 0;
+
+ group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (width));
+
+ if (group_array)
+ {
+ area = gtk_cell_area_context_get_area (context);
+ spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ for (i = 0; i < group_array->len; i++)
+ {
+ CachedSize *size = &g_array_index (group_array, CachedSize, i);
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ /* Dont add spacing for 0 size groups, they can be 0 size because
+ * they contain only invisible cells for this round of requests
+ */
+ if (min_size > 0 && size->nat_size > 0)
+ {
+ min_size += spacing;
+ nat_size += spacing;
+ }
+
+ min_size += size->min_size;
+ nat_size += size->nat_size;
+ }
+ else
+ {
+ min_size = MAX (min_size, size->min_size);
+ nat_size = MAX (nat_size, size->nat_size);
+ }
+ }
+
+ gtk_cell_area_context_push_preferred_height_for_width (context, width, min_size, nat_size);
+ }
+}
+
+static void
+gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+ gint spacing, i;
+ gint min_size = 0, nat_size = 0;
+
+ area = gtk_cell_area_context_get_area (context);
+ spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ for (i = 0; i < priv->base_heights->len; i++)
+ {
+ BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ /* Dont add spacing for 0 size groups, they can be 0 size because
+ * they contain only invisible cells for this round of requests
+ */
+ if (min_size > 0 && size->nat_size > 0)
+ {
+ min_size += spacing;
+ nat_size += spacing;
+ }
+
+ min_size += size->min_size;
+ nat_size += size->nat_size;
+ }
+ else
+ {
+ min_size = MAX (min_size, size->min_size);
+ nat_size = MAX (nat_size, size->nat_size);
+ }
+ }
+
+ gtk_cell_area_context_push_preferred_height (context, min_size, nat_size);
+}
+
+static void
+gtk_cell_area_box_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GArray *group_array;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+ gint spacing, i;
+ gint min_size = 0, nat_size = 0;
+
+ group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (height));
+
+ if (group_array)
+ {
+ area = gtk_cell_area_context_get_area (context);
+ spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ for (i = 0; i < group_array->len; i++)
+ {
+ CachedSize *size = &g_array_index (group_array, CachedSize, i);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ /* Dont add spacing for 0 size groups, they can be 0 size because
+ * they contain only invisible cells for this round of requests
+ */
+ if (min_size > 0 && size->nat_size > 0)
+ {
+ min_size += spacing;
+ nat_size += spacing;
+ }
+
+ min_size += size->min_size;
+ nat_size += size->nat_size;
+ }
+ else
+ {
+ min_size = MAX (min_size, size->min_size);
+ nat_size = MAX (nat_size, size->nat_size);
+ }
+ }
+
+ gtk_cell_area_context_push_preferred_width_for_height (context, height, min_size, nat_size);
+ }
+}
+
+static GtkRequestedSize *
+gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context,
+ GtkOrientation orientation,
+ gint *n_requests)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ GtkRequestedSize *requests;
+ GArray *base_array;
+ BaseSize *size;
+ gint visible_groups = 0;
+ gint i, j;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context), NULL);
+
+ priv = box_context->priv;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ base_array = priv->base_widths;
+ else
+ base_array = priv->base_heights;
+
+ for (i = 0; i < base_array->len; i++)
+ {
+ size = &g_array_index (base_array, BaseSize, i);
+
+ if (size->nat_size > 0)
+ visible_groups++;
+ }
+
+ requests = g_new (GtkRequestedSize, visible_groups);
+
+ for (j = 0, i = 0; i < base_array->len; i++)
+ {
+ size = &g_array_index (base_array, BaseSize, i);
+
+ if (size->nat_size > 0)
+ {
+ requests[j].data = GINT_TO_POINTER (i);
+ requests[j].minimum_size = size->min_size;
+ requests[j].natural_size = size->nat_size;
+ j++;
+ }
+ }
+
+ if (n_requests)
+ *n_requests = visible_groups;
+
+ return requests;
+}
+
+static GtkCellAreaBoxAllocation *
+allocate_for_orientation (GtkCellAreaBoxContext *context,
+ GtkOrientation orientation,
+ gint spacing,
+ gint size,
+ gint *n_allocs)
+{
+ GtkCellAreaBoxContextPrivate *priv = context->priv;
+ GtkRequestedSize *orientation_sizes;
+ GtkCellAreaBoxAllocation *allocs;
+ gint n_expand_groups = 0;
+ gint i, n_groups, position;
+ gint extra_size, extra_extra;
+ gint avail_size = size;
+
+ orientation_sizes =
+ gtk_cell_area_box_context_get_requests (context, orientation, &n_groups);
+
+ /* Count groups that expand */
+ for (i = 0; i < n_groups; i++)
+ {
+ BaseSize *size;
+ gint group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ size = &g_array_index (priv->base_widths, BaseSize, group_idx);
+ else
+ size = &g_array_index (priv->base_heights, BaseSize, group_idx);
+
+ if (size->expand)
+ n_expand_groups++;
+ }
+
+ /* First start by naturally allocating space among groups */
+ avail_size -= (n_groups - 1) * spacing;
+ for (i = 0; i < n_groups; i++)
+ avail_size -= orientation_sizes[i].minimum_size;
+
+ avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, orientation_sizes);
+
+ /* Calculate/distribute expand for groups */
+ if (n_expand_groups > 0)
+ {
+ extra_size = avail_size / n_expand_groups;
+ extra_extra = avail_size % n_expand_groups;
+ }
+ else
+ extra_size = extra_extra = 0;
+
+ allocs = g_new (GtkCellAreaBoxAllocation, n_groups);
+
+ for (position = 0, i = 0; i < n_groups; i++)
+ {
+ BaseSize *base_size = &g_array_index (priv->base_widths, BaseSize, i);
+
+ allocs[i].group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
+ allocs[i].position = position;
+ allocs[i].size = orientation_sizes[i].minimum_size;
+
+ if (base_size->expand)
+ {
+ allocs[i].size += extra_size;
+ if (extra_extra)
+ {
+ allocs[i].size++;
+ extra_extra--;
+ }
+ }
+
+ position += allocs[i].size;
+ position += spacing;
+ }
+
+ if (n_allocs)
+ *n_allocs = n_groups;
+
+ g_free (orientation_sizes);
+
+ return allocs;
+}
+
+static void
+gtk_cell_area_box_context_allocate_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+
+ area = gtk_cell_area_context_get_area (context);
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+
+ g_free (priv->orientation_allocs);
+ priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, width,
+ &priv->n_orientation_allocs);
+ }
+
+ GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_width (context, width);
+}
+
+static void
+gtk_cell_area_box_context_allocate_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
+ GtkCellAreaBoxContextPrivate *priv = box_context->priv;
+ GtkCellArea *area;
+ GtkOrientation orientation;
+
+ area = gtk_cell_area_context_get_area (context);
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+
+ g_free (priv->orientation_allocs);
+ priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, height,
+ &priv->n_orientation_allocs);
+ }
+
+ GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_height (context, height);
+}
+
+/*************************************************************
+ * API *
+ *************************************************************/
+void
+gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
+ guint n_groups,
+ gboolean *expand_groups)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ gint i;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+ g_return_if_fail (n_groups == 0 || expand_groups != NULL);
+
+ /* When the group dimensions change, all info must be flushed
+ * Note this already clears the min/nat values on the BaseSizes
+ */
+ gtk_cell_area_context_flush (GTK_CELL_AREA_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_array_set_size (priv->base_widths, n_groups);
+ g_array_set_size (priv->base_heights, n_groups);
+
+ /* Now set the expand info */
+ for (i = 0; i < n_groups; i++)
+ {
+ BaseSize *base_width = &g_array_index (priv->base_widths, BaseSize, i);
+ BaseSize *base_height = &g_array_index (priv->base_heights, BaseSize, i);
+
+ base_width->expand = expand_groups[i];
+ base_height->expand = expand_groups[i];
+ }
+}
+
+void
+gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint minimum_width,
+ gint natural_width)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ BaseSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ size = &g_array_index (priv->base_widths, BaseSize, group_idx);
+ size->min_size = MAX (size->min_size, minimum_width);
+ size->nat_size = MAX (size->nat_size, natural_width);
+}
+
+void
+gtk_cell_area_box_context_push_group_height_for_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ GArray *group_array;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+ if (!group_array)
+ {
+ group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+ g_array_set_size (group_array, priv->base_heights->len);
+
+ g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), group_array);
+ }
+
+ size = &g_array_index (group_array, CachedSize, group_idx);
+ size->min_size = MAX (size->min_size, minimum_height);
+ size->nat_size = MAX (size->nat_size, natural_height);
+}
+
+void
+gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint minimum_height,
+ gint natural_height)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ BaseSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_heights->len);
+
+ size = &g_array_index (priv->base_heights, BaseSize, group_idx);
+ size->min_size = MAX (size->min_size, minimum_height);
+ size->nat_size = MAX (size->nat_size, natural_height);
+}
+
+void
+gtk_cell_area_box_context_push_group_width_for_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ GArray *group_array;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+ if (!group_array)
+ {
+ group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+ g_array_set_size (group_array, priv->base_heights->len);
+
+ g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), group_array);
+ }
+
+ size = &g_array_index (group_array, CachedSize, group_idx);
+ size->min_size = MAX (size->min_size, minimum_width);
+ size->nat_size = MAX (size->nat_size, natural_width);
+}
+
+void
+gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ BaseSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ size = &g_array_index (priv->base_widths, BaseSize, group_idx);
+
+ if (minimum_width)
+ *minimum_width = size->min_size;
+
+ if (natural_width)
+ *natural_width = size->nat_size;
+}
+
+void
+gtk_cell_area_box_context_get_group_height_for_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ GArray *group_array;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+
+ if (group_array)
+ {
+ CachedSize *size = &g_array_index (group_array, CachedSize, group_idx);
+
+ if (minimum_height)
+ *minimum_height = size->min_size;
+
+ if (natural_height)
+ *natural_height = size->nat_size;
+ }
+ else
+ {
+ if (minimum_height)
+ *minimum_height = -1;
+
+ if (natural_height)
+ *natural_height = -1;
+ }
+}
+
+void
+gtk_cell_area_box_context_get_group_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ BaseSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_heights->len);
+
+ size = &g_array_index (priv->base_heights, BaseSize, group_idx);
+
+ if (minimum_height)
+ *minimum_height = size->min_size;
+
+ if (natural_height)
+ *natural_height = size->nat_size;
+}
+
+void
+gtk_cell_area_box_context_get_group_width_for_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+ GArray *group_array;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
+
+ priv = box_context->priv;
+ g_return_if_fail (group_idx < priv->base_widths->len);
+
+ group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+
+ if (group_array)
+ {
+ CachedSize *size = &g_array_index (group_array, CachedSize, group_idx);
+
+ if (minimum_width)
+ *minimum_width = size->min_size;
+
+ if (natural_width)
+ *natural_width = size->nat_size;
+ }
+ else
+ {
+ if (minimum_width)
+ *minimum_width = -1;
+
+ if (natural_width)
+ *natural_width = -1;
+ }
+}
+
+GtkRequestedSize *
+gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
+ gint *n_widths)
+{
+ return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_HORIZONTAL, n_widths);
+}
+
+GtkRequestedSize *
+gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
+ gint *n_heights)
+{
+ return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_VERTICAL, n_heights);
+}
+
+G_CONST_RETURN GtkCellAreaBoxAllocation *
+gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context,
+ gint *n_allocs)
+{
+ GtkCellAreaBoxContextPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context), NULL);
+
+ priv = context->priv;
+
+ *n_allocs = priv->n_orientation_allocs;
+
+ return priv->orientation_allocs;
+}
--- /dev/null
+/* gtkcellareaboxcontext.h
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb@openismus.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_CELL_AREA_BOX_CONTEXT_H__
+#define __GTK_CELL_AREA_BOX_CONTEXT_H__
+
+#include <gtk/gtkcellareacontext.h>
+#include <gtk/gtkcellareabox.h>
+#include <gtk/gtkcellrenderer.h>
+#include <gtk/gtksizerequest.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CELL_AREA_BOX_CONTEXT (gtk_cell_area_box_context_get_type ())
+#define GTK_CELL_AREA_BOX_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_AREA_BOX_CONTEXT, GtkCellAreaBoxContext))
+#define GTK_CELL_AREA_BOX_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_AREA_BOX_CONTEXT, GtkCellAreaBoxContextClass))
+#define GTK_IS_CELL_AREA_BOX_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_AREA_BOX_CONTEXT))
+#define GTK_IS_CELL_AREA_BOX_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_AREA_BOX_CONTEXT))
+#define GTK_CELL_AREA_BOX_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CELL_AREA_BOX_CONTEXT, GtkCellAreaBoxContextClass))
+
+typedef struct _GtkCellAreaBoxContext GtkCellAreaBoxContext;
+typedef struct _GtkCellAreaBoxContextClass GtkCellAreaBoxContextClass;
+typedef struct _GtkCellAreaBoxContextPrivate GtkCellAreaBoxContextPrivate;
+
+struct _GtkCellAreaBoxContext
+{
+ GtkCellAreaContext parent_instance;
+
+ GtkCellAreaBoxContextPrivate *priv;
+};
+
+struct _GtkCellAreaBoxContextClass
+{
+ GtkCellAreaContextClass parent_class;
+
+};
+
+GType gtk_cell_area_box_context_get_type (void) G_GNUC_CONST;
+
+
+/* Initialize group array dimensions */
+void gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
+ guint n_groups,
+ gboolean *expand_groups);
+
+/* Update cell-group sizes */
+void gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint minimum_width,
+ gint natural_width);
+
+void gtk_cell_area_box_context_push_group_height_for_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height);
+
+void gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint minimum_height,
+ gint natural_height);
+
+void gtk_cell_area_box_context_push_group_width_for_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width);
+
+/* Fetch cell-group sizes */
+void gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint *minimum_width,
+ gint *natural_width);
+
+void gtk_cell_area_box_context_get_group_height_for_width (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height);
+
+void gtk_cell_area_box_context_get_group_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint *minimum_height,
+ gint *natural_height);
+
+void gtk_cell_area_box_context_get_group_width_for_height (GtkCellAreaBoxContext *box_context,
+ gint group_idx,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width);
+
+GtkRequestedSize *gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
+ gint *n_widths);
+GtkRequestedSize *gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
+ gint *n_heights);
+
+/* Private context/area interaction */
+typedef struct {
+ gint group_idx; /* Groups containing only invisible cells are not allocated */
+ gint position; /* Relative group allocation position in the orientation of the box */
+ gint size; /* Full allocated size of the cells in this group spacing inclusive */
+} GtkCellAreaBoxAllocation;
+
+G_CONST_RETURN GtkCellAreaBoxAllocation *
+gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context,
+ gint *n_allocs);
+
+G_END_DECLS
+
+#endif /* __GTK_CELL_AREA_BOX_CONTEXT_H__ */
+++ /dev/null
-/* gtkcellareaboxiter.c
- *
- * Copyright (C) 2010 Openismus GmbH
- *
- * Authors:
- * Tristan Van Berkom <tristanvb@openismus.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "gtkintl.h"
-#include "gtkcellareabox.h"
-#include "gtkcellareaboxiter.h"
-#include "gtkorientable.h"
-
-/* GObjectClass */
-static void gtk_cell_area_box_iter_finalize (GObject *object);
-
-/* GtkCellAreaIterClass */
-static void gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter);
-static void gtk_cell_area_box_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width);
-static void gtk_cell_area_box_iter_flush_preferred_height (GtkCellAreaIter *iter);
-static void gtk_cell_area_box_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height);
-static void gtk_cell_area_box_iter_flush_allocation (GtkCellAreaIter *iter);
-static void gtk_cell_area_box_iter_sum_preferred_width (GtkCellAreaIter *iter);
-static void gtk_cell_area_box_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width);
-static void gtk_cell_area_box_iter_sum_preferred_height (GtkCellAreaIter *iter);
-static void gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height);
-static void gtk_cell_area_box_iter_allocate_width (GtkCellAreaIter *iter,
- gint width);
-static void gtk_cell_area_box_iter_allocate_height (GtkCellAreaIter *iter,
- gint height);
-
-static void free_cache_array (GArray *array);
-
-/* CachedSize management */
-typedef struct {
- gint min_size;
- gint nat_size;
-} CachedSize;
-
-typedef struct {
- gint min_size;
- gint nat_size;
- gboolean expand;
-} BaseSize;
-
-struct _GtkCellAreaBoxIterPrivate
-{
- /* Table of per renderer CachedSizes */
- GArray *base_widths;
- GArray *base_heights;
-
- /* Table of per height/width hash tables of per renderer CachedSizes */
- GHashTable *widths;
- GHashTable *heights;
-
- /* Allocation info for this iter if any */
- gint alloc_width;
- gint alloc_height;
- gint n_orientation_allocs;
- GtkCellAreaBoxAllocation *orientation_allocs;
-};
-
-G_DEFINE_TYPE (GtkCellAreaBoxIter, gtk_cell_area_box_iter, GTK_TYPE_CELL_AREA_ITER);
-
-static void
-free_cache_array (GArray *array)
-{
- g_array_free (array, TRUE);
-}
-
-static void
-gtk_cell_area_box_iter_init (GtkCellAreaBoxIter *box_iter)
-{
- GtkCellAreaBoxIterPrivate *priv;
-
- box_iter->priv = G_TYPE_INSTANCE_GET_PRIVATE (box_iter,
- GTK_TYPE_CELL_AREA_BOX_ITER,
- GtkCellAreaBoxIterPrivate);
- priv = box_iter->priv;
-
- priv->base_widths = g_array_new (FALSE, TRUE, sizeof (BaseSize));
- priv->base_heights = g_array_new (FALSE, TRUE, sizeof (BaseSize));
-
- priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)free_cache_array);
- priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)free_cache_array);
-
- priv->alloc_width = 0;
- priv->alloc_height = 0;
- priv->orientation_allocs = NULL;
- priv->n_orientation_allocs = 0;
-}
-
-static void
-gtk_cell_area_box_iter_class_init (GtkCellAreaBoxIterClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GtkCellAreaIterClass *iter_class = GTK_CELL_AREA_ITER_CLASS (class);
-
- /* GObjectClass */
- object_class->finalize = gtk_cell_area_box_iter_finalize;
-
- iter_class->flush_preferred_width = gtk_cell_area_box_iter_flush_preferred_width;
- iter_class->flush_preferred_height_for_width = gtk_cell_area_box_iter_flush_preferred_height_for_width;
- iter_class->flush_preferred_height = gtk_cell_area_box_iter_flush_preferred_height;
- iter_class->flush_preferred_width_for_height = gtk_cell_area_box_iter_flush_preferred_width_for_height;
- iter_class->flush_allocation = gtk_cell_area_box_iter_flush_allocation;
-
- iter_class->sum_preferred_width = gtk_cell_area_box_iter_sum_preferred_width;
- iter_class->sum_preferred_height_for_width = gtk_cell_area_box_iter_sum_preferred_height_for_width;
- iter_class->sum_preferred_height = gtk_cell_area_box_iter_sum_preferred_height;
- iter_class->sum_preferred_width_for_height = gtk_cell_area_box_iter_sum_preferred_width_for_height;
-
- iter_class->allocate_width = gtk_cell_area_box_iter_allocate_width;
- iter_class->allocate_height = gtk_cell_area_box_iter_allocate_height;
-
- g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxIterPrivate));
-}
-
-/*************************************************************
- * GObjectClass *
- *************************************************************/
-static void
-gtk_cell_area_box_iter_finalize (GObject *object)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (object);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
-
- g_array_free (priv->base_widths, TRUE);
- g_array_free (priv->base_heights, TRUE);
- g_hash_table_destroy (priv->widths);
- g_hash_table_destroy (priv->heights);
-
- g_free (priv->orientation_allocs);
-
- G_OBJECT_CLASS (gtk_cell_area_box_iter_parent_class)->finalize (object);
-}
-
-/*************************************************************
- * GtkCellAreaIterClass *
- *************************************************************/
-static void
-gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- gint i;
-
- for (i = 0; i < priv->base_widths->len; i++)
- {
- BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
-
- size->min_size = 0;
- size->nat_size = 0;
- }
-
- GTK_CELL_AREA_ITER_CLASS
- (gtk_cell_area_box_iter_parent_class)->flush_preferred_width (iter);
-}
-
-static void
-gtk_cell_area_box_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
-
- /* Flush all sizes for special -1 value */
- if (width < 0)
- g_hash_table_remove_all (priv->heights);
- else
- g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
-
- GTK_CELL_AREA_ITER_CLASS
- (gtk_cell_area_box_iter_parent_class)->flush_preferred_height_for_width (iter, width);
-}
-
-static void
-gtk_cell_area_box_iter_flush_preferred_height (GtkCellAreaIter *iter)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- gint i;
-
- for (i = 0; i < priv->base_heights->len; i++)
- {
- BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
-
- size->min_size = 0;
- size->nat_size = 0;
- }
-
- GTK_CELL_AREA_ITER_CLASS
- (gtk_cell_area_box_iter_parent_class)->flush_preferred_height (iter);
-}
-
-static void
-gtk_cell_area_box_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
-
- /* Flush all sizes for special -1 value */
- if (height < 0)
- g_hash_table_remove_all (priv->widths);
- else
- g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
-
- GTK_CELL_AREA_ITER_CLASS
- (gtk_cell_area_box_iter_parent_class)->flush_preferred_width_for_height (iter, height);
-}
-
-static void
-gtk_cell_area_box_iter_flush_allocation (GtkCellAreaIter *iter)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
-
- g_free (priv->orientation_allocs);
- priv->orientation_allocs = NULL;
- priv->n_orientation_allocs = 0;
-}
-
-static void
-gtk_cell_area_box_iter_sum_preferred_width (GtkCellAreaIter *iter)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GtkCellArea *area;
- GtkOrientation orientation;
- gint spacing, i;
- gint min_size = 0, nat_size = 0;
-
- area = gtk_cell_area_iter_get_area (iter);
- spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- for (i = 0; i < priv->base_widths->len; i++)
- {
- BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- /* Dont add spacing for 0 size groups, they can be 0 size because
- * they contain only invisible cells for this round of requests
- */
- if (min_size > 0 && size->nat_size > 0)
- {
- min_size += spacing;
- nat_size += spacing;
- }
-
- min_size += size->min_size;
- nat_size += size->nat_size;
- }
- else
- {
- min_size = MAX (min_size, size->min_size);
- nat_size = MAX (nat_size, size->nat_size);
- }
- }
-
- gtk_cell_area_iter_push_preferred_width (iter, min_size, nat_size);
-}
-
-static void
-gtk_cell_area_box_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GArray *group_array;
- GtkCellArea *area;
- GtkOrientation orientation;
- gint spacing, i;
- gint min_size = 0, nat_size = 0;
-
- group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (width));
-
- if (group_array)
- {
- area = gtk_cell_area_iter_get_area (iter);
- spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- for (i = 0; i < group_array->len; i++)
- {
- CachedSize *size = &g_array_index (group_array, CachedSize, i);
-
- if (orientation == GTK_ORIENTATION_VERTICAL)
- {
- /* Dont add spacing for 0 size groups, they can be 0 size because
- * they contain only invisible cells for this round of requests
- */
- if (min_size > 0 && size->nat_size > 0)
- {
- min_size += spacing;
- nat_size += spacing;
- }
-
- min_size += size->min_size;
- nat_size += size->nat_size;
- }
- else
- {
- min_size = MAX (min_size, size->min_size);
- nat_size = MAX (nat_size, size->nat_size);
- }
- }
-
- gtk_cell_area_iter_push_preferred_height_for_width (iter, width, min_size, nat_size);
- }
-}
-
-static void
-gtk_cell_area_box_iter_sum_preferred_height (GtkCellAreaIter *iter)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GtkCellArea *area;
- GtkOrientation orientation;
- gint spacing, i;
- gint min_size = 0, nat_size = 0;
-
- area = gtk_cell_area_iter_get_area (iter);
- spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- for (i = 0; i < priv->base_heights->len; i++)
- {
- BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
-
- if (orientation == GTK_ORIENTATION_VERTICAL)
- {
- /* Dont add spacing for 0 size groups, they can be 0 size because
- * they contain only invisible cells for this round of requests
- */
- if (min_size > 0 && size->nat_size > 0)
- {
- min_size += spacing;
- nat_size += spacing;
- }
-
- min_size += size->min_size;
- nat_size += size->nat_size;
- }
- else
- {
- min_size = MAX (min_size, size->min_size);
- nat_size = MAX (nat_size, size->nat_size);
- }
- }
-
- gtk_cell_area_iter_push_preferred_height (iter, min_size, nat_size);
-}
-
-static void
-gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GArray *group_array;
- GtkCellArea *area;
- GtkOrientation orientation;
- gint spacing, i;
- gint min_size = 0, nat_size = 0;
-
- group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (height));
-
- if (group_array)
- {
- area = gtk_cell_area_iter_get_area (iter);
- spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- for (i = 0; i < group_array->len; i++)
- {
- CachedSize *size = &g_array_index (group_array, CachedSize, i);
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- /* Dont add spacing for 0 size groups, they can be 0 size because
- * they contain only invisible cells for this round of requests
- */
- if (min_size > 0 && size->nat_size > 0)
- {
- min_size += spacing;
- nat_size += spacing;
- }
-
- min_size += size->min_size;
- nat_size += size->nat_size;
- }
- else
- {
- min_size = MAX (min_size, size->min_size);
- nat_size = MAX (nat_size, size->nat_size);
- }
- }
-
- gtk_cell_area_iter_push_preferred_width_for_height (iter, height, min_size, nat_size);
- }
-}
-
-static GtkRequestedSize *
-gtk_cell_area_box_iter_get_requests (GtkCellAreaBoxIter *box_iter,
- GtkOrientation orientation,
- gint *n_requests)
-{
- GtkCellAreaBoxIterPrivate *priv;
- GtkRequestedSize *requests;
- GArray *base_array;
- BaseSize *size;
- gint visible_groups = 0;
- gint i, j;
-
- g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
-
- priv = box_iter->priv;
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- base_array = priv->base_widths;
- else
- base_array = priv->base_heights;
-
- for (i = 0; i < base_array->len; i++)
- {
- size = &g_array_index (base_array, BaseSize, i);
-
- if (size->nat_size > 0)
- visible_groups++;
- }
-
- requests = g_new (GtkRequestedSize, visible_groups);
-
- for (j = 0, i = 0; i < base_array->len; i++)
- {
- size = &g_array_index (base_array, BaseSize, i);
-
- if (size->nat_size > 0)
- {
- requests[j].data = GINT_TO_POINTER (i);
- requests[j].minimum_size = size->min_size;
- requests[j].natural_size = size->nat_size;
- j++;
- }
- }
-
- if (n_requests)
- *n_requests = visible_groups;
-
- return requests;
-}
-
-static GtkCellAreaBoxAllocation *
-allocate_for_orientation (GtkCellAreaBoxIter *iter,
- GtkOrientation orientation,
- gint spacing,
- gint size,
- gint *n_allocs)
-{
- GtkCellAreaBoxIterPrivate *priv = iter->priv;
- GtkRequestedSize *orientation_sizes;
- GtkCellAreaBoxAllocation *allocs;
- gint n_expand_groups = 0;
- gint i, n_groups, position;
- gint extra_size, extra_extra;
- gint avail_size = size;
-
- orientation_sizes =
- gtk_cell_area_box_iter_get_requests (iter, orientation, &n_groups);
-
- /* Count groups that expand */
- for (i = 0; i < n_groups; i++)
- {
- BaseSize *size;
- gint group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- size = &g_array_index (priv->base_widths, BaseSize, group_idx);
- else
- size = &g_array_index (priv->base_heights, BaseSize, group_idx);
-
- if (size->expand)
- n_expand_groups++;
- }
-
- /* First start by naturally allocating space among groups */
- avail_size -= (n_groups - 1) * spacing;
- for (i = 0; i < n_groups; i++)
- avail_size -= orientation_sizes[i].minimum_size;
-
- avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, orientation_sizes);
-
- /* Calculate/distribute expand for groups */
- if (n_expand_groups > 0)
- {
- extra_size = avail_size / n_expand_groups;
- extra_extra = avail_size % n_expand_groups;
- }
- else
- extra_size = extra_extra = 0;
-
- allocs = g_new (GtkCellAreaBoxAllocation, n_groups);
-
- for (position = 0, i = 0; i < n_groups; i++)
- {
- BaseSize *base_size = &g_array_index (priv->base_widths, BaseSize, i);
-
- allocs[i].group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
- allocs[i].position = position;
- allocs[i].size = orientation_sizes[i].minimum_size;
-
- if (base_size->expand)
- {
- allocs[i].size += extra_size;
- if (extra_extra)
- {
- allocs[i].size++;
- extra_extra--;
- }
- }
-
- position += allocs[i].size;
- position += spacing;
- }
-
- if (n_allocs)
- *n_allocs = n_groups;
-
- g_free (orientation_sizes);
-
- return allocs;
-}
-
-static void
-gtk_cell_area_box_iter_allocate_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GtkCellArea *area;
- GtkOrientation orientation;
-
- area = gtk_cell_area_iter_get_area (iter);
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-
- g_free (priv->orientation_allocs);
- priv->orientation_allocs = allocate_for_orientation (box_iter, orientation, spacing, width,
- &priv->n_orientation_allocs);
- }
-
- GTK_CELL_AREA_ITER_CLASS (gtk_cell_area_box_iter_parent_class)->allocate_width (iter, width);
-}
-
-static void
-gtk_cell_area_box_iter_allocate_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
- GtkCellArea *area;
- GtkOrientation orientation;
-
- area = gtk_cell_area_iter_get_area (iter);
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
- if (orientation == GTK_ORIENTATION_VERTICAL)
- {
- gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-
- g_free (priv->orientation_allocs);
- priv->orientation_allocs = allocate_for_orientation (box_iter, orientation, spacing, height,
- &priv->n_orientation_allocs);
- }
-
- GTK_CELL_AREA_ITER_CLASS (gtk_cell_area_box_iter_parent_class)->allocate_height (iter, height);
-}
-
-/*************************************************************
- * API *
- *************************************************************/
-void
-gtk_cell_area_box_init_groups (GtkCellAreaBoxIter *box_iter,
- guint n_groups,
- gboolean *expand_groups)
-{
- GtkCellAreaBoxIterPrivate *priv;
- gint i;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (n_groups == 0 || expand_groups != NULL);
-
- /* When the group dimensions change, all info must be flushed
- * Note this already clears the min/nat values on the BaseSizes
- */
- gtk_cell_area_iter_flush (GTK_CELL_AREA_ITER (box_iter));
-
- priv = box_iter->priv;
- g_array_set_size (priv->base_widths, n_groups);
- g_array_set_size (priv->base_heights, n_groups);
-
- /* Now set the expand info */
- for (i = 0; i < n_groups; i++)
- {
- BaseSize *base_width = &g_array_index (priv->base_widths, BaseSize, i);
- BaseSize *base_height = &g_array_index (priv->base_heights, BaseSize, i);
-
- base_width->expand = expand_groups[i];
- base_height->expand = expand_groups[i];
- }
-}
-
-void
-gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint minimum_width,
- gint natural_width)
-{
- GtkCellAreaBoxIterPrivate *priv;
- BaseSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- size = &g_array_index (priv->base_widths, BaseSize, group_idx);
- size->min_size = MAX (size->min_size, minimum_width);
- size->nat_size = MAX (size->nat_size, natural_width);
-}
-
-void
-gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_width,
- gint minimum_height,
- gint natural_height)
-{
- GtkCellAreaBoxIterPrivate *priv;
- GArray *group_array;
- CachedSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
- if (!group_array)
- {
- group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
- g_array_set_size (group_array, priv->base_heights->len);
-
- g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), group_array);
- }
-
- size = &g_array_index (group_array, CachedSize, group_idx);
- size->min_size = MAX (size->min_size, minimum_height);
- size->nat_size = MAX (size->nat_size, natural_height);
-}
-
-void
-gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint minimum_height,
- gint natural_height)
-{
- GtkCellAreaBoxIterPrivate *priv;
- BaseSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_heights->len);
-
- size = &g_array_index (priv->base_heights, BaseSize, group_idx);
- size->min_size = MAX (size->min_size, minimum_height);
- size->nat_size = MAX (size->nat_size, natural_height);
-}
-
-void
-gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_height,
- gint minimum_width,
- gint natural_width)
-{
- GtkCellAreaBoxIterPrivate *priv;
- GArray *group_array;
- CachedSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
- if (!group_array)
- {
- group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
- g_array_set_size (group_array, priv->base_heights->len);
-
- g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), group_array);
- }
-
- size = &g_array_index (group_array, CachedSize, group_idx);
- size->min_size = MAX (size->min_size, minimum_width);
- size->nat_size = MAX (size->nat_size, natural_width);
-}
-
-void
-gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint *minimum_width,
- gint *natural_width)
-{
- GtkCellAreaBoxIterPrivate *priv;
- BaseSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- size = &g_array_index (priv->base_widths, BaseSize, group_idx);
-
- if (minimum_width)
- *minimum_width = size->min_size;
-
- if (natural_width)
- *natural_width = size->nat_size;
-}
-
-void
-gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_width,
- gint *minimum_height,
- gint *natural_height)
-{
- GtkCellAreaBoxIterPrivate *priv;
- GArray *group_array;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
-
- if (group_array)
- {
- CachedSize *size = &g_array_index (group_array, CachedSize, group_idx);
-
- if (minimum_height)
- *minimum_height = size->min_size;
-
- if (natural_height)
- *natural_height = size->nat_size;
- }
- else
- {
- if (minimum_height)
- *minimum_height = -1;
-
- if (natural_height)
- *natural_height = -1;
- }
-}
-
-void
-gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint *minimum_height,
- gint *natural_height)
-{
- GtkCellAreaBoxIterPrivate *priv;
- BaseSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_heights->len);
-
- size = &g_array_index (priv->base_heights, BaseSize, group_idx);
-
- if (minimum_height)
- *minimum_height = size->min_size;
-
- if (natural_height)
- *natural_height = size->nat_size;
-}
-
-void
-gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_height,
- gint *minimum_width,
- gint *natural_width)
-{
- GtkCellAreaBoxIterPrivate *priv;
- GArray *group_array;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
-
- priv = box_iter->priv;
- g_return_if_fail (group_idx < priv->base_widths->len);
-
- group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
-
- if (group_array)
- {
- CachedSize *size = &g_array_index (group_array, CachedSize, group_idx);
-
- if (minimum_width)
- *minimum_width = size->min_size;
-
- if (natural_width)
- *natural_width = size->nat_size;
- }
- else
- {
- if (minimum_width)
- *minimum_width = -1;
-
- if (natural_width)
- *natural_width = -1;
- }
-}
-
-GtkRequestedSize *
-gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
- gint *n_widths)
-{
- return gtk_cell_area_box_iter_get_requests (box_iter, GTK_ORIENTATION_HORIZONTAL, n_widths);
-}
-
-GtkRequestedSize *
-gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
- gint *n_heights)
-{
- return gtk_cell_area_box_iter_get_requests (box_iter, GTK_ORIENTATION_VERTICAL, n_heights);
-}
-
-G_CONST_RETURN GtkCellAreaBoxAllocation *
-gtk_cell_area_box_iter_get_orientation_allocs (GtkCellAreaBoxIter *iter,
- gint *n_allocs)
-{
- GtkCellAreaBoxIterPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter), NULL);
-
- priv = iter->priv;
-
- *n_allocs = priv->n_orientation_allocs;
-
- return priv->orientation_allocs;
-}
+++ /dev/null
-/* gtkcellareaboxiter.h
- *
- * Copyright (C) 2010 Openismus GmbH
- *
- * Authors:
- * Tristan Van Berkom <tristanvb@openismus.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#ifndef __GTK_CELL_AREA_BOX_ITER_H__
-#define __GTK_CELL_AREA_BOX_ITER_H__
-
-#include <gtk/gtkcellareaiter.h>
-#include <gtk/gtkcellareabox.h>
-#include <gtk/gtkcellrenderer.h>
-#include <gtk/gtksizerequest.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_CELL_AREA_BOX_ITER (gtk_cell_area_box_iter_get_type ())
-#define GTK_CELL_AREA_BOX_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_AREA_BOX_ITER, GtkCellAreaBoxIter))
-#define GTK_CELL_AREA_BOX_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_AREA_BOX_ITER, GtkCellAreaBoxIterClass))
-#define GTK_IS_CELL_AREA_BOX_ITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_AREA_BOX_ITER))
-#define GTK_IS_CELL_AREA_BOX_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_AREA_BOX_ITER))
-#define GTK_CELL_AREA_BOX_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CELL_AREA_BOX_ITER, GtkCellAreaBoxIterClass))
-
-typedef struct _GtkCellAreaBoxIter GtkCellAreaBoxIter;
-typedef struct _GtkCellAreaBoxIterClass GtkCellAreaBoxIterClass;
-typedef struct _GtkCellAreaBoxIterPrivate GtkCellAreaBoxIterPrivate;
-
-struct _GtkCellAreaBoxIter
-{
- GtkCellAreaIter parent_instance;
-
- GtkCellAreaBoxIterPrivate *priv;
-};
-
-struct _GtkCellAreaBoxIterClass
-{
- GtkCellAreaIterClass parent_class;
-
-};
-
-GType gtk_cell_area_box_iter_get_type (void) G_GNUC_CONST;
-
-
-/* Initialize group array dimensions */
-void gtk_cell_area_box_init_groups (GtkCellAreaBoxIter *box_iter,
- guint n_groups,
- gboolean *expand_groups);
-
-/* Update cell-group sizes */
-void gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint minimum_width,
- gint natural_width);
-
-void gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_width,
- gint minimum_height,
- gint natural_height);
-
-void gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint minimum_height,
- gint natural_height);
-
-void gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_height,
- gint minimum_width,
- gint natural_width);
-
-/* Fetch cell-group sizes */
-void gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint *minimum_width,
- gint *natural_width);
-
-void gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_width,
- gint *minimum_height,
- gint *natural_height);
-
-void gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint *minimum_height,
- gint *natural_height);
-
-void gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
- gint group_idx,
- gint for_height,
- gint *minimum_width,
- gint *natural_width);
-
-GtkRequestedSize *gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
- gint *n_widths);
-GtkRequestedSize *gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
- gint *n_heights);
-
-/* Private iter/area interaction */
-typedef struct {
- gint group_idx; /* Groups containing only invisible cells are not allocated */
- gint position; /* Relative group allocation position in the orientation of the box */
- gint size; /* Full allocated size of the cells in this group spacing inclusive */
-} GtkCellAreaBoxAllocation;
-
-G_CONST_RETURN GtkCellAreaBoxAllocation *
-gtk_cell_area_box_iter_get_orientation_allocs (GtkCellAreaBoxIter *iter,
- gint *n_allocs);
-
-G_END_DECLS
-
-#endif /* __GTK_CELL_AREA_BOX_ITER_H__ */
--- /dev/null
+/* gtkcellareacontext.c
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb@openismus.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkcellareacontext.h"
+#include "gtkprivate.h"
+
+/* GObjectClass */
+static void gtk_cell_area_context_finalize (GObject *object);
+static void gtk_cell_area_context_dispose (GObject *object);
+static void gtk_cell_area_context_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_cell_area_context_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+/* GtkCellAreaContextClass */
+static void gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context);
+static void gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width);
+static void gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context);
+static void gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height);
+static void gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context);
+static void gtk_cell_area_context_real_allocate_width (GtkCellAreaContext *context,
+ gint width);
+static void gtk_cell_area_context_real_allocate_height (GtkCellAreaContext *context,
+ gint height);
+
+/* CachedSize management */
+typedef struct {
+ gint min_size;
+ gint nat_size;
+} CachedSize;
+
+static CachedSize *cached_size_new (gint min_size, gint nat_size);
+static void cached_size_free (CachedSize *size);
+
+struct _GtkCellAreaContextPrivate
+{
+ GtkCellArea *cell_area;
+
+ gint min_width;
+ gint nat_width;
+ gint min_height;
+ gint nat_height;
+ gint alloc_width;
+ gint alloc_height;
+
+ GHashTable *widths;
+ GHashTable *heights;
+};
+
+enum {
+ PROP_0,
+ PROP_CELL_AREA,
+ PROP_MIN_WIDTH,
+ PROP_NAT_WIDTH,
+ PROP_MIN_HEIGHT,
+ PROP_NAT_HEIGHT
+};
+
+enum {
+ SIGNAL_WIDTH_CHANGED,
+ SIGNAL_HEIGHT_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint cell_area_context_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
+
+static void
+gtk_cell_area_context_init (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context,
+ GTK_TYPE_CELL_AREA_CONTEXT,
+ GtkCellAreaContextPrivate);
+ priv = context->priv;
+
+ priv->min_width = -1;
+ priv->nat_width = -1;
+ priv->min_height = -1;
+ priv->nat_height = -1;
+ priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)cached_size_free);
+ priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)cached_size_free);
+}
+
+static void
+gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ /* GObjectClass */
+ object_class->finalize = gtk_cell_area_context_finalize;
+ object_class->dispose = gtk_cell_area_context_dispose;
+ object_class->get_property = gtk_cell_area_context_get_property;
+ object_class->set_property = gtk_cell_area_context_set_property;
+
+ /* GtkCellAreaContextClass */
+ class->flush_preferred_width = gtk_cell_area_context_real_flush_preferred_width;
+ class->flush_preferred_height_for_width = gtk_cell_area_context_real_flush_preferred_height_for_width;
+ class->flush_preferred_height = gtk_cell_area_context_real_flush_preferred_height;
+ class->flush_preferred_width_for_height = gtk_cell_area_context_real_flush_preferred_width_for_height;
+ class->flush_allocation = gtk_cell_area_context_real_flush_allocation;
+
+ class->sum_preferred_width = NULL;
+ class->sum_preferred_height_for_width = NULL;
+ class->sum_preferred_height = NULL;
+ class->sum_preferred_width_for_height = NULL;
+
+ class->allocate_width = gtk_cell_area_context_real_allocate_width;
+ class->allocate_height = gtk_cell_area_context_real_allocate_height;
+
+ cell_area_context_signals[SIGNAL_HEIGHT_CHANGED] =
+ g_signal_new (I_("height-changed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, /* Class offset (just a notification, no class handler) */
+ NULL, NULL,
+ _gtk_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ cell_area_context_signals[SIGNAL_WIDTH_CHANGED] =
+ g_signal_new (I_("width-changed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, /* Class offset (just a notification, no class handler) */
+ NULL, NULL,
+ _gtk_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ g_object_class_install_property (object_class,
+ PROP_CELL_AREA,
+ g_param_spec_object ("area",
+ P_("Area"),
+ P_("The Cell Area this context was created for"),
+ GTK_TYPE_CELL_AREA,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_MIN_WIDTH,
+ g_param_spec_int ("minimum-width",
+ P_("Minimum Width"),
+ P_("Minimum cached width"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_NAT_WIDTH,
+ g_param_spec_int ("natural-width",
+ P_("Minimum Width"),
+ P_("Minimum cached width"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_MIN_HEIGHT,
+ g_param_spec_int ("minimum-height",
+ P_("Minimum Height"),
+ P_("Minimum cached height"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_NAT_HEIGHT,
+ g_param_spec_int ("natural-height",
+ P_("Minimum Height"),
+ P_("Minimum cached height"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
+}
+
+
+
+/*************************************************************
+ * Cached Sizes *
+ *************************************************************/
+static CachedSize *
+cached_size_new (gint min_size,
+ gint nat_size)
+{
+ CachedSize *size = g_slice_new (CachedSize);
+
+ size->min_size = min_size;
+ size->nat_size = nat_size;
+
+ return size;
+}
+
+static void
+cached_size_free (CachedSize *size)
+{
+ g_slice_free (CachedSize, size);
+}
+
+/*************************************************************
+ * GObjectClass *
+ *************************************************************/
+static void
+gtk_cell_area_context_finalize (GObject *object)
+{
+ GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ g_hash_table_destroy (priv->widths);
+ g_hash_table_destroy (priv->heights);
+
+ G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->finalize (object);
+}
+
+static void
+gtk_cell_area_context_dispose (GObject *object)
+{
+ GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ if (priv->cell_area)
+ {
+ g_object_unref (priv->cell_area);
+
+ priv->cell_area = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->dispose (object);
+}
+
+static void
+gtk_cell_area_context_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ switch (prop_id)
+ {
+ case PROP_CELL_AREA:
+ priv->cell_area = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_cell_area_context_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ switch (prop_id)
+ {
+ case PROP_CELL_AREA:
+ g_value_set_object (value, priv->cell_area);
+ break;
+ case PROP_MIN_WIDTH:
+ g_value_set_int (value, priv->min_width);
+ break;
+ case PROP_NAT_WIDTH:
+ g_value_set_int (value, priv->nat_width);
+ break;
+ case PROP_MIN_HEIGHT:
+ g_value_set_int (value, priv->min_height);
+ break;
+ case PROP_NAT_HEIGHT:
+ g_value_set_int (value, priv->nat_height);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*************************************************************
+ * GtkCellAreaContextClass *
+ *************************************************************/
+static void
+gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ priv->min_width = -1;
+ priv->nat_width = -1;
+
+ g_object_freeze_notify (G_OBJECT (context));
+ g_object_notify (G_OBJECT (context), "minimum-width");
+ g_object_notify (G_OBJECT (context), "natural-width");
+ g_object_thaw_notify (G_OBJECT (context));
+}
+
+static void
+notify_invalid_height (gpointer width_ptr,
+ CachedSize *size,
+ GtkCellAreaContext *context)
+{
+ gint width = GPOINTER_TO_INT (width_ptr);
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED],
+ 0, width, -1, -1);
+}
+
+static void
+gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (width < 0)
+ {
+ g_hash_table_foreach (priv->heights, (GHFunc)notify_invalid_height, context);
+ g_hash_table_remove_all (priv->heights);
+ }
+ else
+ {
+ g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED],
+ 0, width, -1, -1);
+ }
+}
+
+static void
+gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ priv->min_height = -1;
+ priv->nat_height = -1;
+
+ g_object_freeze_notify (G_OBJECT (context));
+ g_object_notify (G_OBJECT (context), "minimum-height");
+ g_object_notify (G_OBJECT (context), "natural-height");
+ g_object_thaw_notify (G_OBJECT (context));
+}
+
+static void
+notify_invalid_width (gpointer height_ptr,
+ CachedSize *size,
+ GtkCellAreaContext *context)
+{
+ gint height = GPOINTER_TO_INT (height_ptr);
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED],
+ 0, height, -1, -1);
+}
+
+static void
+gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (height < 0)
+ {
+ g_hash_table_foreach (priv->widths, (GHFunc)notify_invalid_width, context);
+ g_hash_table_remove_all (priv->widths);
+ }
+ else
+ {
+ g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED],
+ 0, height, -1, -1);
+ }
+}
+
+static void
+gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ priv->alloc_width = 0;
+ priv->alloc_height = 0;
+}
+
+static void
+gtk_cell_area_context_real_allocate_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ priv->alloc_width = width;
+}
+
+static void
+gtk_cell_area_context_real_allocate_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ priv->alloc_height = height;
+}
+
+
+/*************************************************************
+ * API *
+ *************************************************************/
+GtkCellArea *
+gtk_cell_area_context_get_area (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
+
+ priv = context->priv;
+
+ return priv->cell_area;
+}
+
+void
+gtk_cell_area_context_flush (GtkCellAreaContext *context)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ gtk_cell_area_context_flush_preferred_width (context);
+ gtk_cell_area_context_flush_preferred_height_for_width (context, -1);
+ gtk_cell_area_context_flush_preferred_height (context);
+ gtk_cell_area_context_flush_preferred_width_for_height (context, -1);
+ gtk_cell_area_context_flush_allocation (context);
+}
+
+void
+gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_width (context);
+}
+
+void
+gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_height_for_width (context, for_width);
+}
+
+void
+gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_height (context);
+}
+
+void
+gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_width_for_height (context, for_height);
+}
+
+void
+gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_allocation (context);
+}
+
+void
+gtk_cell_area_context_sum_preferred_width (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_width)
+ class->sum_preferred_width (context);
+}
+
+void
+gtk_cell_area_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_height_for_width)
+ class->sum_preferred_height_for_width (context, for_width);
+}
+
+void
+gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_height)
+ class->sum_preferred_height (context);
+}
+
+void
+gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_width_for_height)
+ class->sum_preferred_width_for_height (context, for_height);
+}
+
+void
+gtk_cell_area_context_allocate_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ class->allocate_width (context, width);
+}
+
+void
+gtk_cell_area_context_allocate_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ class->allocate_height (context, height);
+}
+
+void
+gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ if (minimum_width)
+ *minimum_width = priv->min_width;
+
+ if (natural_width)
+ *natural_width = priv->nat_width;
+}
+
+void
+gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+
+ if (size)
+ {
+ if (minimum_height)
+ *minimum_height = size->min_size;
+
+ if (natural_height)
+ *natural_height = size->nat_size;
+ }
+ else
+ {
+ if (minimum_height)
+ *minimum_height = -1;
+
+ if (natural_height)
+ *natural_height = -1;
+ }
+}
+
+void
+gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ if (minimum_height)
+ *minimum_height = priv->min_height;
+
+ if (natural_height)
+ *natural_height = priv->nat_height;
+}
+
+void
+gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+
+ if (size)
+ {
+ if (minimum_width)
+ *minimum_width = size->min_size;
+
+ if (natural_width)
+ *natural_width = size->nat_size;
+ }
+ else
+ {
+ if (minimum_width)
+ *minimum_width = -1;
+
+ if (natural_width)
+ *natural_width = -1;
+ }
+}
+
+void
+gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
+ gint *width,
+ gint *height)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ if (width)
+ *width = priv->alloc_width;
+
+ if (height)
+ *height = priv->alloc_height;
+}
+
+void
+gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
+ gint minimum_width,
+ gint natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ g_object_freeze_notify (G_OBJECT (context));
+
+ if (minimum_width > priv->min_width)
+ {
+ priv->min_width = minimum_width;
+
+ g_object_notify (G_OBJECT (context), "minimum-width");
+ }
+
+ if (natural_width > priv->nat_width)
+ {
+ priv->nat_width = natural_width;
+
+ g_object_notify (G_OBJECT (context), "natural-width");
+ }
+
+ g_object_thaw_notify (G_OBJECT (context));
+}
+
+void
+gtk_cell_area_context_push_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+
+ if (!size)
+ {
+ size = cached_size_new (minimum_height, natural_height);
+
+ g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), size);
+
+ changed = TRUE;
+ }
+ else
+ {
+ if (minimum_height > size->min_size)
+ {
+ size->min_size = minimum_height;
+ changed = TRUE;
+ }
+
+ if (natural_height > size->nat_size)
+ {
+ size->nat_size = natural_height;
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED], 0,
+ for_width, size->min_size, size->nat_size);
+}
+
+void
+gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
+ gint minimum_height,
+ gint natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ g_object_freeze_notify (G_OBJECT (context));
+
+ if (minimum_height > priv->min_height)
+ {
+ priv->min_height = minimum_height;
+
+ g_object_notify (G_OBJECT (context), "minimum-height");
+ }
+
+ if (natural_height > priv->nat_height)
+ {
+ priv->nat_height = natural_height;
+
+ g_object_notify (G_OBJECT (context), "natural-height");
+ }
+
+ g_object_thaw_notify (G_OBJECT (context));
+}
+
+void
+gtk_cell_area_context_push_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+
+ if (!size)
+ {
+ size = cached_size_new (minimum_width, natural_width);
+
+ g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), size);
+
+ changed = TRUE;
+ }
+ else
+ {
+ if (minimum_width > size->min_size)
+ {
+ size->min_size = minimum_width;
+ changed = TRUE;
+ }
+
+ if (natural_width > size->nat_size)
+ {
+ size->nat_size = natural_width;
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED], 0,
+ for_height, size->min_size, size->nat_size);
+}
--- /dev/null
+/* gtkcellareacontext.h
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb@openismus.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_CELL_AREA_CONTEXT_H__
+#define __GTK_CELL_AREA_CONTEXT_H__
+
+#include <gtk/gtkcellarea.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CELL_AREA_CONTEXT (gtk_cell_area_context_get_type ())
+#define GTK_CELL_AREA_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_AREA_CONTEXT, GtkCellAreaContext))
+#define GTK_CELL_AREA_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_AREA_CONTEXT, GtkCellAreaContextClass))
+#define GTK_IS_CELL_AREA_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_AREA_CONTEXT))
+#define GTK_IS_CELL_AREA_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_AREA_CONTEXT))
+#define GTK_CELL_AREA_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CELL_AREA_CONTEXT, GtkCellAreaContextClass))
+
+typedef struct _GtkCellAreaContextPrivate GtkCellAreaContextPrivate;
+typedef struct _GtkCellAreaContextClass GtkCellAreaContextClass;
+
+struct _GtkCellAreaContext
+{
+ GObject parent_instance;
+
+ GtkCellAreaContextPrivate *priv;
+};
+
+struct _GtkCellAreaContextClass
+{
+ GObjectClass parent_class;
+
+ /* Subclasses can use this to flush their alignments/allocations */
+ void (* flush_preferred_width) (GtkCellAreaContext *context);
+ void (* flush_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width);
+ void (* flush_preferred_height) (GtkCellAreaContext *context);
+ void (* flush_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height);
+ void (* flush_allocation) (GtkCellAreaContext *context);
+
+ /* These must be invoked after a series of requests before consulting
+ * the context values, implementors use this to push the overall
+ * requests while acconting for any internal alignments */
+ void (* sum_preferred_width) (GtkCellAreaContext *context);
+ void (* sum_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width);
+ void (* sum_preferred_height) (GtkCellAreaContext *context);
+ void (* sum_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height);
+
+ /* Store an allocation value for a GtkCellArea contextual to a range of
+ * treemodel rows */
+ void (* allocate_width) (GtkCellAreaContext *context,
+ gint width);
+ void (* allocate_height) (GtkCellAreaContext *context,
+ gint height);
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+GType gtk_cell_area_context_get_type (void) G_GNUC_CONST;
+
+GtkCellArea *gtk_cell_area_context_get_area (GtkCellAreaContext *context);
+
+/* Apis for GtkCellArea clients to flush the cache */
+void gtk_cell_area_context_flush (GtkCellAreaContext *context);
+void gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context);
+void gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width);
+void gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context);
+void gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height);
+void gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context);
+
+/* Apis for GtkCellArea clients to sum up the results of a series of requests, this
+ * call is required to reduce the processing while calculating the size of each row */
+void gtk_cell_area_context_sum_preferred_width (GtkCellAreaContext *context);
+void gtk_cell_area_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width);
+void gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context);
+void gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height);
+
+/* Apis to set an allocation size in one dimension or another, the subclass specific context
+ * will store allocated positions/sizes for individual cells or groups of cells */
+void gtk_cell_area_context_allocate_width (GtkCellAreaContext *context,
+ gint width);
+void gtk_cell_area_context_allocate_height (GtkCellAreaContext *context,
+ gint height);
+
+/* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
+void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
+ gint *width,
+ gint *height);
+
+/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
+void gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
+ gint minimum_width,
+ gint natural_width);
+void gtk_cell_area_context_push_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height);
+void gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
+ gint minimum_height,
+ gint natural_height);
+void gtk_cell_area_context_push_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width);
+
+G_END_DECLS
+
+#endif /* __GTK_CELL_AREA_CONTEXT_H__ */
+++ /dev/null
-/* gtkcellareaiter.c
- *
- * Copyright (C) 2010 Openismus GmbH
- *
- * Authors:
- * Tristan Van Berkom <tristanvb@openismus.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "gtkintl.h"
-#include "gtkmarshalers.h"
-#include "gtkcellareaiter.h"
-#include "gtkprivate.h"
-
-/* GObjectClass */
-static void gtk_cell_area_iter_finalize (GObject *object);
-static void gtk_cell_area_iter_dispose (GObject *object);
-static void gtk_cell_area_iter_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_cell_area_iter_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-
-/* GtkCellAreaIterClass */
-static void gtk_cell_area_iter_real_flush_preferred_width (GtkCellAreaIter *iter);
-static void gtk_cell_area_iter_real_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width);
-static void gtk_cell_area_iter_real_flush_preferred_height (GtkCellAreaIter *iter);
-static void gtk_cell_area_iter_real_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height);
-static void gtk_cell_area_iter_real_flush_allocation (GtkCellAreaIter *iter);
-static void gtk_cell_area_iter_real_allocate_width (GtkCellAreaIter *iter,
- gint width);
-static void gtk_cell_area_iter_real_allocate_height (GtkCellAreaIter *iter,
- gint height);
-
-/* CachedSize management */
-typedef struct {
- gint min_size;
- gint nat_size;
-} CachedSize;
-
-static CachedSize *cached_size_new (gint min_size, gint nat_size);
-static void cached_size_free (CachedSize *size);
-
-struct _GtkCellAreaIterPrivate
-{
- GtkCellArea *cell_area;
-
- gint min_width;
- gint nat_width;
- gint min_height;
- gint nat_height;
- gint alloc_width;
- gint alloc_height;
-
- GHashTable *widths;
- GHashTable *heights;
-};
-
-enum {
- PROP_0,
- PROP_CELL_AREA,
- PROP_MIN_WIDTH,
- PROP_NAT_WIDTH,
- PROP_MIN_HEIGHT,
- PROP_NAT_HEIGHT
-};
-
-enum {
- SIGNAL_WIDTH_CHANGED,
- SIGNAL_HEIGHT_CHANGED,
- LAST_SIGNAL
-};
-
-static guint cell_area_iter_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (GtkCellAreaIter, gtk_cell_area_iter, G_TYPE_OBJECT);
-
-static void
-gtk_cell_area_iter_init (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterPrivate *priv;
-
- iter->priv = G_TYPE_INSTANCE_GET_PRIVATE (iter,
- GTK_TYPE_CELL_AREA_ITER,
- GtkCellAreaIterPrivate);
- priv = iter->priv;
-
- priv->min_width = -1;
- priv->nat_width = -1;
- priv->min_height = -1;
- priv->nat_height = -1;
- priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)cached_size_free);
- priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)cached_size_free);
-}
-
-static void
-gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- /* GObjectClass */
- object_class->finalize = gtk_cell_area_iter_finalize;
- object_class->dispose = gtk_cell_area_iter_dispose;
- object_class->get_property = gtk_cell_area_iter_get_property;
- object_class->set_property = gtk_cell_area_iter_set_property;
-
- /* GtkCellAreaIterClass */
- class->flush_preferred_width = gtk_cell_area_iter_real_flush_preferred_width;
- class->flush_preferred_height_for_width = gtk_cell_area_iter_real_flush_preferred_height_for_width;
- class->flush_preferred_height = gtk_cell_area_iter_real_flush_preferred_height;
- class->flush_preferred_width_for_height = gtk_cell_area_iter_real_flush_preferred_width_for_height;
- class->flush_allocation = gtk_cell_area_iter_real_flush_allocation;
-
- class->sum_preferred_width = NULL;
- class->sum_preferred_height_for_width = NULL;
- class->sum_preferred_height = NULL;
- class->sum_preferred_width_for_height = NULL;
-
- class->allocate_width = gtk_cell_area_iter_real_allocate_width;
- class->allocate_height = gtk_cell_area_iter_real_allocate_height;
-
- cell_area_iter_signals[SIGNAL_HEIGHT_CHANGED] =
- g_signal_new (I_("height-changed"),
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, /* Class offset (just a notification, no class handler) */
- NULL, NULL,
- _gtk_marshal_VOID__INT_INT_INT,
- G_TYPE_NONE, 3,
- G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
-
- cell_area_iter_signals[SIGNAL_WIDTH_CHANGED] =
- g_signal_new (I_("width-changed"),
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, /* Class offset (just a notification, no class handler) */
- NULL, NULL,
- _gtk_marshal_VOID__INT_INT_INT,
- G_TYPE_NONE, 3,
- G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
-
- g_object_class_install_property (object_class,
- PROP_CELL_AREA,
- g_param_spec_object ("area",
- P_("Area"),
- P_("The Cell Area this iter was created for"),
- GTK_TYPE_CELL_AREA,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_MIN_WIDTH,
- g_param_spec_int ("minimum-width",
- P_("Minimum Width"),
- P_("Minimum cached width"),
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_NAT_WIDTH,
- g_param_spec_int ("natural-width",
- P_("Minimum Width"),
- P_("Minimum cached width"),
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_MIN_HEIGHT,
- g_param_spec_int ("minimum-height",
- P_("Minimum Height"),
- P_("Minimum cached height"),
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_NAT_HEIGHT,
- g_param_spec_int ("natural-height",
- P_("Minimum Height"),
- P_("Minimum cached height"),
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READABLE));
-
- g_type_class_add_private (object_class, sizeof (GtkCellAreaIterPrivate));
-}
-
-
-
-/*************************************************************
- * Cached Sizes *
- *************************************************************/
-static CachedSize *
-cached_size_new (gint min_size,
- gint nat_size)
-{
- CachedSize *size = g_slice_new (CachedSize);
-
- size->min_size = min_size;
- size->nat_size = nat_size;
-
- return size;
-}
-
-static void
-cached_size_free (CachedSize *size)
-{
- g_slice_free (CachedSize, size);
-}
-
-/*************************************************************
- * GObjectClass *
- *************************************************************/
-static void
-gtk_cell_area_iter_finalize (GObject *object)
-{
- GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- g_hash_table_destroy (priv->widths);
- g_hash_table_destroy (priv->heights);
-
- G_OBJECT_CLASS (gtk_cell_area_iter_parent_class)->finalize (object);
-}
-
-static void
-gtk_cell_area_iter_dispose (GObject *object)
-{
- GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- if (priv->cell_area)
- {
- g_object_unref (priv->cell_area);
-
- priv->cell_area = NULL;
- }
-
- G_OBJECT_CLASS (gtk_cell_area_iter_parent_class)->dispose (object);
-}
-
-static void
-gtk_cell_area_iter_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- switch (prop_id)
- {
- case PROP_CELL_AREA:
- priv->cell_area = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gtk_cell_area_iter_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- switch (prop_id)
- {
- case PROP_CELL_AREA:
- g_value_set_object (value, priv->cell_area);
- break;
- case PROP_MIN_WIDTH:
- g_value_set_int (value, priv->min_width);
- break;
- case PROP_NAT_WIDTH:
- g_value_set_int (value, priv->nat_width);
- break;
- case PROP_MIN_HEIGHT:
- g_value_set_int (value, priv->min_height);
- break;
- case PROP_NAT_HEIGHT:
- g_value_set_int (value, priv->nat_height);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/*************************************************************
- * GtkCellAreaIterClass *
- *************************************************************/
-static void
-gtk_cell_area_iter_real_flush_preferred_width (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- priv->min_width = -1;
- priv->nat_width = -1;
-
- g_object_freeze_notify (G_OBJECT (iter));
- g_object_notify (G_OBJECT (iter), "minimum-width");
- g_object_notify (G_OBJECT (iter), "natural-width");
- g_object_thaw_notify (G_OBJECT (iter));
-}
-
-static void
-notify_invalid_height (gpointer width_ptr,
- CachedSize *size,
- GtkCellAreaIter *iter)
-{
- gint width = GPOINTER_TO_INT (width_ptr);
-
- /* Notify size invalidated */
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_HEIGHT_CHANGED],
- 0, width, -1, -1);
-}
-
-static void
-gtk_cell_area_iter_real_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- /* Flush all sizes for special -1 value */
- if (width < 0)
- {
- g_hash_table_foreach (priv->heights, (GHFunc)notify_invalid_height, iter);
- g_hash_table_remove_all (priv->heights);
- }
- else
- {
- g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
-
- /* Notify size invalidated */
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_HEIGHT_CHANGED],
- 0, width, -1, -1);
- }
-}
-
-static void
-gtk_cell_area_iter_real_flush_preferred_height (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- priv->min_height = -1;
- priv->nat_height = -1;
-
- g_object_freeze_notify (G_OBJECT (iter));
- g_object_notify (G_OBJECT (iter), "minimum-height");
- g_object_notify (G_OBJECT (iter), "natural-height");
- g_object_thaw_notify (G_OBJECT (iter));
-}
-
-static void
-notify_invalid_width (gpointer height_ptr,
- CachedSize *size,
- GtkCellAreaIter *iter)
-{
- gint height = GPOINTER_TO_INT (height_ptr);
-
- /* Notify size invalidated */
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_WIDTH_CHANGED],
- 0, height, -1, -1);
-}
-
-static void
-gtk_cell_area_iter_real_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- /* Flush all sizes for special -1 value */
- if (height < 0)
- {
- g_hash_table_foreach (priv->widths, (GHFunc)notify_invalid_width, iter);
- g_hash_table_remove_all (priv->widths);
- }
- else
- {
- g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
-
- /* Notify size invalidated */
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_WIDTH_CHANGED],
- 0, height, -1, -1);
- }
-}
-
-static void
-gtk_cell_area_iter_real_flush_allocation (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- priv->alloc_width = 0;
- priv->alloc_height = 0;
-}
-
-static void
-gtk_cell_area_iter_real_allocate_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- priv->alloc_width = width;
-}
-
-static void
-gtk_cell_area_iter_real_allocate_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaIterPrivate *priv = iter->priv;
-
- priv->alloc_height = height;
-}
-
-
-/*************************************************************
- * API *
- *************************************************************/
-GtkCellArea *
-gtk_cell_area_iter_get_area (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_CELL_AREA_ITER (iter), NULL);
-
- priv = iter->priv;
-
- return priv->cell_area;
-}
-
-void
-gtk_cell_area_iter_flush (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- gtk_cell_area_iter_flush_preferred_width (iter);
- gtk_cell_area_iter_flush_preferred_height_for_width (iter, -1);
- gtk_cell_area_iter_flush_preferred_height (iter);
- gtk_cell_area_iter_flush_preferred_width_for_height (iter, -1);
- gtk_cell_area_iter_flush_allocation (iter);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width (iter);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height_for_width (iter, for_width);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height (iter);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width_for_height (iter, for_height);
-}
-
-void
-gtk_cell_area_iter_flush_allocation (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_allocation (iter);
-}
-
-void
-gtk_cell_area_iter_sum_preferred_width (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- if (class->sum_preferred_width)
- class->sum_preferred_width (iter);
-}
-
-void
-gtk_cell_area_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- if (class->sum_preferred_height_for_width)
- class->sum_preferred_height_for_width (iter, for_width);
-}
-
-void
-gtk_cell_area_iter_sum_preferred_height (GtkCellAreaIter *iter)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- if (class->sum_preferred_height)
- class->sum_preferred_height (iter);
-}
-
-void
-gtk_cell_area_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- if (class->sum_preferred_width_for_height)
- class->sum_preferred_width_for_height (iter, for_height);
-}
-
-void
-gtk_cell_area_iter_allocate_width (GtkCellAreaIter *iter,
- gint width)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- class->allocate_width (iter, width);
-}
-
-void
-gtk_cell_area_iter_allocate_height (GtkCellAreaIter *iter,
- gint height)
-{
- GtkCellAreaIterClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
-
- class->allocate_height (iter, height);
-}
-
-void
-gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
- gint *minimum_width,
- gint *natural_width)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- if (minimum_width)
- *minimum_width = priv->min_width;
-
- if (natural_width)
- *natural_width = priv->nat_width;
-}
-
-void
-gtk_cell_area_iter_get_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint *minimum_height,
- gint *natural_height)
-{
- GtkCellAreaIterPrivate *priv;
- CachedSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
-
- if (size)
- {
- if (minimum_height)
- *minimum_height = size->min_size;
-
- if (natural_height)
- *natural_height = size->nat_size;
- }
- else
- {
- if (minimum_height)
- *minimum_height = -1;
-
- if (natural_height)
- *natural_height = -1;
- }
-}
-
-void
-gtk_cell_area_iter_get_preferred_height (GtkCellAreaIter *iter,
- gint *minimum_height,
- gint *natural_height)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- if (minimum_height)
- *minimum_height = priv->min_height;
-
- if (natural_height)
- *natural_height = priv->nat_height;
-}
-
-void
-gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint *minimum_width,
- gint *natural_width)
-{
- GtkCellAreaIterPrivate *priv;
- CachedSize *size;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
-
- if (size)
- {
- if (minimum_width)
- *minimum_width = size->min_size;
-
- if (natural_width)
- *natural_width = size->nat_size;
- }
- else
- {
- if (minimum_width)
- *minimum_width = -1;
-
- if (natural_width)
- *natural_width = -1;
- }
-}
-
-void
-gtk_cell_area_iter_get_allocation (GtkCellAreaIter *iter,
- gint *width,
- gint *height)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- if (width)
- *width = priv->alloc_width;
-
- if (height)
- *height = priv->alloc_height;
-}
-
-void
-gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
- gint minimum_width,
- gint natural_width)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- g_object_freeze_notify (G_OBJECT (iter));
-
- if (minimum_width > priv->min_width)
- {
- priv->min_width = minimum_width;
-
- g_object_notify (G_OBJECT (iter), "minimum-width");
- }
-
- if (natural_width > priv->nat_width)
- {
- priv->nat_width = natural_width;
-
- g_object_notify (G_OBJECT (iter), "natural-width");
- }
-
- g_object_thaw_notify (G_OBJECT (iter));
-}
-
-void
-gtk_cell_area_iter_push_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint minimum_height,
- gint natural_height)
-{
- GtkCellAreaIterPrivate *priv;
- CachedSize *size;
- gboolean changed = FALSE;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
-
- if (!size)
- {
- size = cached_size_new (minimum_height, natural_height);
-
- g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), size);
-
- changed = TRUE;
- }
- else
- {
- if (minimum_height > size->min_size)
- {
- size->min_size = minimum_height;
- changed = TRUE;
- }
-
- if (natural_height > size->nat_size)
- {
- size->nat_size = natural_height;
- changed = TRUE;
- }
- }
-
- if (changed)
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_HEIGHT_CHANGED], 0,
- for_width, size->min_size, size->nat_size);
-}
-
-void
-gtk_cell_area_iter_push_preferred_height (GtkCellAreaIter *iter,
- gint minimum_height,
- gint natural_height)
-{
- GtkCellAreaIterPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- g_object_freeze_notify (G_OBJECT (iter));
-
- if (minimum_height > priv->min_height)
- {
- priv->min_height = minimum_height;
-
- g_object_notify (G_OBJECT (iter), "minimum-height");
- }
-
- if (natural_height > priv->nat_height)
- {
- priv->nat_height = natural_height;
-
- g_object_notify (G_OBJECT (iter), "natural-height");
- }
-
- g_object_thaw_notify (G_OBJECT (iter));
-}
-
-void
-gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint minimum_width,
- gint natural_width)
-{
- GtkCellAreaIterPrivate *priv;
- CachedSize *size;
- gboolean changed = FALSE;
-
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- priv = iter->priv;
-
- size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
-
- if (!size)
- {
- size = cached_size_new (minimum_width, natural_width);
-
- g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), size);
-
- changed = TRUE;
- }
- else
- {
- if (minimum_width > size->min_size)
- {
- size->min_size = minimum_width;
- changed = TRUE;
- }
-
- if (natural_width > size->nat_size)
- {
- size->nat_size = natural_width;
- changed = TRUE;
- }
- }
-
- if (changed)
- g_signal_emit (iter, cell_area_iter_signals[SIGNAL_WIDTH_CHANGED], 0,
- for_height, size->min_size, size->nat_size);
-}
+++ /dev/null
-/* gtkcellareaiter.h
- *
- * Copyright (C) 2010 Openismus GmbH
- *
- * Authors:
- * Tristan Van Berkom <tristanvb@openismus.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#ifndef __GTK_CELL_AREA_ITER_H__
-#define __GTK_CELL_AREA_ITER_H__
-
-#include <gtk/gtkcellarea.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_CELL_AREA_ITER (gtk_cell_area_iter_get_type ())
-#define GTK_CELL_AREA_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_AREA_ITER, GtkCellAreaIter))
-#define GTK_CELL_AREA_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_AREA_ITER, GtkCellAreaIterClass))
-#define GTK_IS_CELL_AREA_ITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_AREA_ITER))
-#define GTK_IS_CELL_AREA_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_AREA_ITER))
-#define GTK_CELL_AREA_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CELL_AREA_ITER, GtkCellAreaIterClass))
-
-typedef struct _GtkCellAreaIterPrivate GtkCellAreaIterPrivate;
-typedef struct _GtkCellAreaIterClass GtkCellAreaIterClass;
-
-struct _GtkCellAreaIter
-{
- GObject parent_instance;
-
- GtkCellAreaIterPrivate *priv;
-};
-
-struct _GtkCellAreaIterClass
-{
- GObjectClass parent_class;
-
- /* Subclasses can use this to flush their alignments/allocations */
- void (* flush_preferred_width) (GtkCellAreaIter *iter);
- void (* flush_preferred_height_for_width) (GtkCellAreaIter *iter,
- gint width);
- void (* flush_preferred_height) (GtkCellAreaIter *iter);
- void (* flush_preferred_width_for_height) (GtkCellAreaIter *iter,
- gint height);
- void (* flush_allocation) (GtkCellAreaIter *iter);
-
- /* These must be invoked after a series of requests before consulting
- * the iter values, implementors use this to push the overall
- * requests while acconting for any internal alignments */
- void (* sum_preferred_width) (GtkCellAreaIter *iter);
- void (* sum_preferred_height_for_width) (GtkCellAreaIter *iter,
- gint width);
- void (* sum_preferred_height) (GtkCellAreaIter *iter);
- void (* sum_preferred_width_for_height) (GtkCellAreaIter *iter,
- gint height);
-
- /* Store an allocation value for a GtkCellArea contextual to a range of
- * treemodel rows */
- void (* allocate_width) (GtkCellAreaIter *iter,
- gint width);
- void (* allocate_height) (GtkCellAreaIter *iter,
- gint height);
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-GType gtk_cell_area_iter_get_type (void) G_GNUC_CONST;
-
-GtkCellArea *gtk_cell_area_iter_get_area (GtkCellAreaIter *iter);
-
-/* Apis for GtkCellArea clients to flush the cache */
-void gtk_cell_area_iter_flush (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width);
-void gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height);
-void gtk_cell_area_iter_flush_allocation (GtkCellAreaIter *iter);
-
-/* Apis for GtkCellArea clients to sum up the results of a series of requests, this
- * call is required to reduce the processing while calculating the size of each row */
-void gtk_cell_area_iter_sum_preferred_width (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width);
-void gtk_cell_area_iter_sum_preferred_height (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height);
-
-/* Apis to set an allocation size in one dimension or another, the subclass specific iter
- * will store allocated positions/sizes for individual cells or groups of cells */
-void gtk_cell_area_iter_allocate_width (GtkCellAreaIter *iter,
- gint width);
-void gtk_cell_area_iter_allocate_height (GtkCellAreaIter *iter,
- gint height);
-
-/* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
-void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
- gint *minimum_width,
- gint *natural_width);
-void gtk_cell_area_iter_get_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_iter_get_preferred_height (GtkCellAreaIter *iter,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint *minimum_width,
- gint *natural_width);
-void gtk_cell_area_iter_get_allocation (GtkCellAreaIter *iter,
- gint *width,
- gint *height);
-
-/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
-void gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
- gint minimum_width,
- gint natural_width);
-void gtk_cell_area_iter_push_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint minimum_height,
- gint natural_height);
-void gtk_cell_area_iter_push_preferred_height (GtkCellAreaIter *iter,
- gint minimum_height,
- gint natural_height);
-void gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint minimum_width,
- gint natural_width);
-
-G_END_DECLS
-
-#endif /* __GTK_CELL_AREA_ITER_H__ */
static void cell_area_scaffold_activate (CellAreaScaffold *scaffold);
/* CellArea/GtkTreeModel callbacks */
-static void size_changed_cb (GtkCellAreaIter *iter,
+static void size_changed_cb (GtkCellAreaContext *context,
GParamSpec *pspec,
CellAreaScaffold *scaffold);
static void focus_changed_cb (GtkCellArea *area,
gulong row_deleted_id;
gulong rows_reordered_id;
- /* The area rendering the data and a global iter */
- GtkCellArea *area;
- GtkCellAreaIter *iter;
+ /* The area rendering the data and a global context */
+ GtkCellArea *area;
+ GtkCellAreaContext *context;
/* Cache some info about rows (hieghts etc) */
GArray *row_data;
CellAreaScaffoldPrivate);
priv = scaffold->priv;
- priv->area = gtk_cell_area_box_new ();
- priv->iter = gtk_cell_area_create_iter (priv->area);
+ priv->area = gtk_cell_area_box_new ();
+ priv->context = gtk_cell_area_create_context (priv->area);
priv->row_data = g_array_new (FALSE, FALSE, sizeof (RowData));
gtk_widget_set_can_focus (GTK_WIDGET (scaffold), TRUE);
priv->size_changed_id =
- g_signal_connect (priv->iter, "notify",
+ g_signal_connect (priv->context, "notify",
G_CALLBACK (size_changed_cb), scaffold);
priv->focus_changed_id =
cell_area_scaffold_set_model (scaffold, NULL);
- if (priv->iter)
+ if (priv->context)
{
/* Disconnect signals */
- g_signal_handler_disconnect (priv->iter, priv->size_changed_id);
+ g_signal_handler_disconnect (priv->context, priv->size_changed_id);
- g_object_unref (priv->iter);
- priv->iter = NULL;
+ g_object_unref (priv->context);
+ priv->context = NULL;
priv->size_changed_id = 0;
}
}
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
- gtk_cell_area_render (priv->area, priv->iter, widget, cr,
+ gtk_cell_area_render (priv->area, priv->context, widget, cr,
&background_area, &render_area, flags,
(have_focus && i == priv->focus_row));
if (!priv->model)
return;
- g_signal_handler_block (priv->iter, priv->size_changed_id);
+ g_signal_handler_block (priv->context, priv->size_changed_id);
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (priv->area));
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_get_preferred_width (priv->area, priv->iter, widget, &min, &nat);
+ gtk_cell_area_get_preferred_width (priv->area, priv->context, widget, &min, &nat);
else
- gtk_cell_area_get_preferred_height (priv->area, priv->iter, widget, &min, &nat);
+ gtk_cell_area_get_preferred_height (priv->area, priv->context, widget, &min, &nat);
valid = gtk_tree_model_iter_next (priv->model, &iter);
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_iter_sum_preferred_width (priv->iter);
+ gtk_cell_area_context_sum_preferred_width (priv->context);
else
- gtk_cell_area_iter_sum_preferred_height (priv->iter);
+ gtk_cell_area_context_sum_preferred_height (priv->context);
- g_signal_handler_unblock (priv->iter, priv->size_changed_id);
+ g_signal_handler_unblock (priv->context, priv->size_changed_id);
}
static void
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_get_preferred_height_for_width (priv->area, priv->iter, widget,
+ gtk_cell_area_get_preferred_height_for_width (priv->area, priv->context, widget,
for_size, &data->size, NULL);
else
- gtk_cell_area_get_preferred_width_for_height (priv->area, priv->iter, widget,
+ gtk_cell_area_get_preferred_width_for_height (priv->area, priv->context, widget,
for_size, &data->size, NULL);
i++;
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (priv->area));
- /* Cache the per-row sizes and allocate the iter */
+ /* Cache the per-row sizes and allocate the context */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- gtk_cell_area_iter_allocate_width (priv->iter, allocation->width - priv->indent);
+ gtk_cell_area_context_allocate_width (priv->context, allocation->width - priv->indent);
get_row_sizes (scaffold, priv->row_data, allocation->width - priv->indent);
}
else
{
- gtk_cell_area_iter_allocate_height (priv->iter, allocation->height - priv->indent);
+ gtk_cell_area_context_allocate_height (priv->context, allocation->height - priv->indent);
get_row_sizes (scaffold, priv->row_data, allocation->height - priv->indent);
}
}
{
request_all_base (scaffold);
- gtk_cell_area_iter_get_preferred_width (priv->iter, minimum_size, natural_size);
+ gtk_cell_area_context_get_preferred_width (priv->context, minimum_size, natural_size);
*minimum_size += priv->indent;
*natural_size += priv->indent;
{
request_all_base (scaffold);
- gtk_cell_area_iter_get_preferred_height (priv->iter, minimum_size, natural_size);
+ gtk_cell_area_context_get_preferred_height (priv->context, minimum_size, natural_size);
*minimum_size += priv->indent;
*natural_size += priv->indent;
{
/* XXX A real implementation would assemble GtkCellRendererState flags here */
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
- handled = gtk_cell_area_event (priv->area, priv->iter, GTK_WIDGET (scaffold),
+ handled = gtk_cell_area_event (priv->area, priv->context, GTK_WIDGET (scaffold),
(GdkEvent *)event, &event_area, 0);
break;
}
{
/* XXX A real implementation would assemble GtkCellRendererState flags here */
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
- handled = gtk_cell_area_event (priv->area, priv->iter, GTK_WIDGET (scaffold),
+ handled = gtk_cell_area_event (priv->area, priv->context, GTK_WIDGET (scaffold),
(GdkEvent *)event, &event_area, 0);
break;
}
cell_area.width = data->size;
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
- gtk_cell_area_activate (priv->area, priv->iter, widget, &cell_area, GTK_CELL_RENDERER_FOCUSED);
+ gtk_cell_area_activate (priv->area, priv->context, widget, &cell_area, GTK_CELL_RENDERER_FOCUSED);
break;
}
* CellArea/GtkTreeModel callbacks *
*********************************************************/
static void
-size_changed_cb (GtkCellAreaIter *iter,
- GParamSpec *pspec,
- CellAreaScaffold *scaffold)
+size_changed_cb (GtkCellAreaContext *context,
+ GParamSpec *pspec,
+ CellAreaScaffold *scaffold)
{
if (!strcmp (pspec->name, "minimum-width") ||
!strcmp (pspec->name, "natural-width") ||
else
g_array_set_size (priv->row_data, 0);
- /* Data changed, lets flush the iter and consequently queue resize and
+ /* Data changed, lets flush the context and consequently queue resize and
* start everything over again (note this is definitly far from optimized) */
- gtk_cell_area_iter_flush (priv->iter);
+ gtk_cell_area_context_flush (priv->context);
}
static void